init
This commit is contained in:
424
DataPRO/DASFactory/DASFactory.HID.cs
Normal file
424
DataPRO/DASFactory/DASFactory.HID.cs
Normal file
@@ -0,0 +1,424 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Forms;
|
||||
using System.Threading;
|
||||
using System.Diagnostics;
|
||||
using DTS.DASLib.Connection;
|
||||
using DTS.DASLib.Service;
|
||||
using DTS.DASLib.Connection.USBFramework;
|
||||
using DTS.DASLib.Communication;
|
||||
using DTS.DASLib.Command.SLICE;
|
||||
using DTS.DASLib.Command;
|
||||
using DTS.DASLib.DASResource;
|
||||
using DTS.DAS.Concepts;
|
||||
|
||||
namespace DTS.DASLib.DASFactory
|
||||
{
|
||||
internal class HIDHandling: WindowsNotification
|
||||
{
|
||||
/// <summary>
|
||||
/// Timeout in milliseconds to connect an HID device
|
||||
/// </summary>
|
||||
public int ConnectHIDTimeout { get; set; }
|
||||
|
||||
private IDeviceSetup deviceHandler { get; set; }
|
||||
|
||||
#region Registry handling
|
||||
|
||||
protected List<String> RegKeys = new List<string>();
|
||||
|
||||
protected void ReadRegKeys()
|
||||
{
|
||||
try
|
||||
{
|
||||
RegKeys.Clear();
|
||||
ReadHIDRegKeys();
|
||||
}
|
||||
catch(System.Exception)
|
||||
{
|
||||
// we don't care what is was, an empty list is fine
|
||||
}
|
||||
}
|
||||
|
||||
protected void ReadHIDRegKeys()
|
||||
{
|
||||
// HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\HID\VID_1CB9&PID_0003\6&29dd55fe&0&0000
|
||||
//RegKeys.Clear();
|
||||
var ourKey = Microsoft.Win32.Registry.LocalMachine;
|
||||
var ourName = @"SYSTEM\CurrentControlSet\Enum\HID\" + DTS_VENDOR_ID_STR + "&" + deviceHandler.GetProductIDString();
|
||||
ourKey = ourKey.OpenSubKey(ourName);
|
||||
//if ourKey is null, this will throw an exception, but since nothing is done in the current
|
||||
//exception handler, the old code was just bypassing this code anyhow (when there's an exception)
|
||||
//6/8/2010 - dtm
|
||||
if (null != ourKey)
|
||||
{
|
||||
foreach (var subKey in ourKey.GetSubKeyNames())
|
||||
{
|
||||
RegKeys.Add(subKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public HIDHandling(DASFactory _factory, UpdateFinishedEventHandler _SerialUpdateFinished, IDeviceSetup _deviceHandler)
|
||||
: base(_factory, _SerialUpdateFinished, _deviceHandler.GetGuid())
|
||||
{
|
||||
deviceHandler = _deviceHandler;
|
||||
|
||||
ReadRegKeys();
|
||||
|
||||
ConnectHIDTimeout = 1000; // 1000 ms
|
||||
}
|
||||
|
||||
#region HID WinProc's
|
||||
|
||||
protected override void NotificationDeviceArrived(ref System.Windows.Forms.Message m)
|
||||
{
|
||||
try
|
||||
{
|
||||
DTS.Utilities.Logging.APILogger.LogString("HIDArrived: A device has been connected");
|
||||
// this can either be a HEADS or a SLICE device being connected
|
||||
|
||||
// \\?\hid#vid_1cb9&pid_0002#6&29dd55fe&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}
|
||||
var bcdi = (DeviceManagementDeclarations.DEV_BROADCAST_DEVICEINTERFACE)Marshal.PtrToStructure(m.LParam, typeof(DeviceManagementDeclarations.DEV_BROADCAST_DEVICEINTERFACE));
|
||||
var devNameArr = bcdi.dbcc_name.Split('#');
|
||||
var foundKey = RegKeys.Find(delegate(String ss) { return ss == devNameArr[2]; });
|
||||
if(foundKey != null)
|
||||
{
|
||||
SerialUpdateActionQueue.EnqueueConnect();
|
||||
}
|
||||
else
|
||||
{
|
||||
ReadRegKeys();
|
||||
}
|
||||
}
|
||||
catch(System.Exception ex)
|
||||
{
|
||||
DTS.Utilities.Logging.APILogger.LogString("HIDArrived caught an exception: " + ex.Message + " " + ex.StackTrace);
|
||||
MessageBox.Show("HIDArrived caught an exception: " + ex.Message + " " + ex.StackTrace, "Error");
|
||||
}
|
||||
finally
|
||||
{
|
||||
DTS.Utilities.Logging.APILogger.LogString("HIDArrived: Exit");
|
||||
}
|
||||
}
|
||||
|
||||
protected override void NotificationDeviceRemoved(ref System.Windows.Forms.Message m)
|
||||
{
|
||||
try
|
||||
{
|
||||
DTS.Utilities.Logging.APILogger.LogString("HIDRemoved: A device has been disconnected");
|
||||
//var bcdi2 = (DeviceManagementDeclarations.DEV_BROADCAST_DEVICEINTERFACE)Marshal.PtrToStructure(m.LParam, typeof(DeviceManagementDeclarations.DEV_BROADCAST_DEVICEINTERFACE));
|
||||
SerialUpdateActionQueue.EnqueueDisconnect();
|
||||
}
|
||||
catch(System.Exception ex)
|
||||
{
|
||||
DTS.Utilities.Logging.APILogger.LogString("HIDRemoved caught an exception: " + ex.Message + " " + ex.StackTrace);
|
||||
MessageBox.Show("HIDRemoved caught an exception: " + ex.Message + " " + ex.StackTrace, "Error");
|
||||
}
|
||||
finally
|
||||
{
|
||||
DTS.Utilities.Logging.APILogger.LogString("HIDRemoved: Exit");
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
protected override void UpdateDisconnectedDevices()
|
||||
{
|
||||
ConnectNewDevices(new GetDeviceStrings(delegate() { return GetListOfConnectedHIDDevices(); }),
|
||||
new GetDeviceStrings(delegate() { return GetConnectedStrings(); }),
|
||||
new GetICommunication(delegate() { return deviceHandler.GetICommunication(); }),
|
||||
new GetIConnectedDevice(delegate(ICommunication comm) { return deviceHandler.GetIConnectedDevice(comm); }),
|
||||
deviceHandler.GetDASType(),
|
||||
deviceHandler,
|
||||
ConnectHIDTimeout);
|
||||
}
|
||||
|
||||
protected override void UpdateConnectedDevices()
|
||||
{
|
||||
DisconnectRemovedDevices(new GetDeviceStrings(delegate()
|
||||
{
|
||||
return GetListOfConnectedHIDDevices();
|
||||
}),
|
||||
new DASTypeFilter(delegate(ConnectedDevice dev)
|
||||
{
|
||||
return deviceHandler.IsCorrectType(dev);
|
||||
}),
|
||||
new ConnectedDevice2Communication(delegate(ConnectedDevice dev)
|
||||
{
|
||||
return deviceHandler.GetICommunication(dev);
|
||||
}),
|
||||
deviceHandler.GetDASType(),
|
||||
ConnectHIDTimeout);
|
||||
}
|
||||
|
||||
#region Connection functions
|
||||
|
||||
private List<string> GetAllHIDDevices()
|
||||
{
|
||||
string[] AllHIDDevicePathNames = new string[128];
|
||||
try
|
||||
{
|
||||
// Fill an array with the device path names of all attached HIDs.
|
||||
if(!MyDeviceManagement.FindDeviceFromGuid(deviceHandler.GetGuid(), ref AllHIDDevicePathNames))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
// loop thru the array and copy the new ones (that actually contain something)
|
||||
// over to the list newNames
|
||||
List<string> newNames = new List<string>();
|
||||
for(int i = 0; i < AllHIDDevicePathNames.Length; i++)
|
||||
{
|
||||
if(string.IsNullOrEmpty(AllHIDDevicePathNames[i]))
|
||||
continue;
|
||||
|
||||
// protect against windows giving us more than one of the same
|
||||
if(newNames.Find(delegate(String str) { return str.Equals(AllHIDDevicePathNames[i], StringComparison.OrdinalIgnoreCase); }) == null)
|
||||
{
|
||||
// no, we haven't added it yet so do it now
|
||||
newNames.Add(AllHIDDevicePathNames[i]);
|
||||
}
|
||||
}
|
||||
return newNames;
|
||||
}
|
||||
|
||||
private int OpenDevicePath(string devicePath)
|
||||
{
|
||||
int devHandle;
|
||||
try
|
||||
{
|
||||
devHandle = FileIODeclarations.CreateFile(devicePath,
|
||||
0,
|
||||
FileIODeclarations.FILE_SHARE_READ | FileIODeclarations.FILE_SHARE_WRITE,
|
||||
ref Security,
|
||||
FileIODeclarations.OPEN_EXISTING,
|
||||
0,
|
||||
0);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return FileIODeclarations.INVALID_HANDLE_VALUE;
|
||||
}
|
||||
return devHandle;
|
||||
}
|
||||
|
||||
private List<string> FilterHIDDeviceList(List<string> newNames, int vid, int pid)
|
||||
{
|
||||
if(newNames == null || newNames.Count == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// now we have a list of new unique devices, make a new list containing only the ones that are of the right type
|
||||
List<string> newRecorderNames = new List<string>();
|
||||
foreach(string devicePath in newNames)
|
||||
{
|
||||
try
|
||||
{
|
||||
int devHandle = OpenDevicePath(devicePath);
|
||||
if(devHandle == FileIODeclarations.INVALID_HANDLE_VALUE)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
HIDevice deviceHID = new HIDevice();
|
||||
// Set the Size property of DeviceAttributes to the number of bytes in the structure.
|
||||
deviceHID.DeviceAttributes.Size = Marshal.SizeOf(deviceHID.DeviceAttributes);
|
||||
int Result = HIDDeclarations.HidD_GetAttributes(devHandle, ref deviceHID.DeviceAttributes);
|
||||
if(Result == 0)
|
||||
{
|
||||
// There was a problem in retrieving the information.
|
||||
FileIODeclarations.CloseHandle(devHandle);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Find out if the device matches the one we're looking for.
|
||||
if(deviceHID.DeviceAttributes.VendorID != vid ||
|
||||
deviceHID.DeviceAttributes.ProductID != pid)
|
||||
{
|
||||
// It's not a match, so close the handle.
|
||||
FileIODeclarations.CloseHandle(devHandle);
|
||||
continue;
|
||||
}
|
||||
// we don't need this handle anymore
|
||||
FileIODeclarations.CloseHandle(devHandle);
|
||||
|
||||
// it's a new one
|
||||
newRecorderNames.Add(devicePath);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignore it, try the next one
|
||||
}
|
||||
}
|
||||
|
||||
return newRecorderNames;
|
||||
}
|
||||
|
||||
private List<string> GetListOfConnectedHIDDevices()
|
||||
{
|
||||
var newNames = GetAllHIDDevices();
|
||||
if(newNames == null || newNames.Count == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// now we have a list of new unique devices, make a new list containing only the ones that are of the right type
|
||||
List<string> newRecorderNames;
|
||||
try
|
||||
{
|
||||
newRecorderNames = FilterHIDDeviceList(newNames, DTS_VENDOR_ID, deviceHandler.GetProductID());
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return newRecorderNames;
|
||||
}
|
||||
|
||||
#endregion
|
||||
/*
|
||||
#region HID update (not updated yet to separate callbacks)
|
||||
|
||||
private bool UpdateConnectedHID()
|
||||
{
|
||||
bool devicesFound = false;
|
||||
try
|
||||
{
|
||||
DTS.Utilities.Logging.APILogger.LogString("UpdateConnectedHID: Enter");
|
||||
// get a list of SLICE units currently connected thru HID
|
||||
var ConnectedHIDSlices = GetListOfConnectedHIDSlices();
|
||||
devicesFound = (null != ConnectedHIDSlices && ConnectedHIDSlices.Count > 0);
|
||||
|
||||
if(devicesFound)
|
||||
{
|
||||
// subtract the ones we already know about
|
||||
var NewHIDSlices = ConnectedHIDSlices.Except(GetConnectedStrings());
|
||||
|
||||
// add the new ones
|
||||
foreach(var devPath in NewHIDSlices)
|
||||
{
|
||||
var newHIDSlice = new HIDUSBSlice();
|
||||
var newConnectedHIDSlice = new ConnectedHIDSlice(newHIDSlice);
|
||||
|
||||
// try to connect it
|
||||
newHIDSlice.Connect(devPath,
|
||||
ConnectHIDCallback,
|
||||
new DeviceAndWaitTuple(newConnectedHIDSlice, null),
|
||||
ConnectHIDTimeout);
|
||||
}
|
||||
|
||||
// now see if we have to remove any
|
||||
IEnumerable<ConnectedDevice> DevicesToRemove;
|
||||
lock(ConnectedDevicesLock)
|
||||
{
|
||||
DevicesToRemove = from dev in ConnectedDevices
|
||||
where !ConnectedHIDSlices.Contains(dev.dev.ConnectString)
|
||||
select dev;
|
||||
}
|
||||
// each one in this list must be disconnected
|
||||
foreach(var dev in DevicesToRemove)
|
||||
{
|
||||
// this is one of those places where we need to get to the ICommunication part
|
||||
((dev.dev as IConnectedDAS).Comm as ICommunication).Disconnect(false,
|
||||
ConnectHIDCallback,
|
||||
new DeviceAndWaitTuple(dev, null),
|
||||
ConnectHIDTimeout);
|
||||
}
|
||||
}
|
||||
return devicesFound;
|
||||
}
|
||||
catch(System.Exception ex)
|
||||
{
|
||||
DTS.Utilities.Logging.APILogger.LogString(string.Format("DASFactory.UpdateConnectedHID: Exception {0} at {1}", ex.Message, ex.StackTrace));
|
||||
MessageBox.Show(string.Format("DASFactory.UpdateConnectedHID: Exception {0} at {1}", ex.Message, ex.StackTrace));
|
||||
return false;
|
||||
}
|
||||
finally
|
||||
{
|
||||
DTS.Utilities.Logging.APILogger.LogString("UpdateConnectedWinUSB: Exit");
|
||||
}
|
||||
return devicesFound;
|
||||
}
|
||||
|
||||
// this is our callback for both connect and disconnect
|
||||
private bool ConnectHIDCallback(ICommunicationReport report)
|
||||
{
|
||||
Debug.Assert(report.UserState is DeviceAndWaitTuple);
|
||||
var DeviceParameter = (report.UserState as DeviceAndWaitTuple).Device;
|
||||
|
||||
var newHidUSB = DeviceParameter as ConnectedDevice;
|
||||
ConnectedDevice newDev;
|
||||
if(null != newHidUSB)
|
||||
{
|
||||
newDev = newHidUSB;
|
||||
}
|
||||
else
|
||||
{
|
||||
newDev = new ConnectedDevice();
|
||||
newDev.dev = DeviceParameter as IConnectedDevice;
|
||||
newDev.dastype = ConnectedDevice.DASType.HID_SLICE;
|
||||
// assume not in update mode
|
||||
newDev.InUpdateMode = false;
|
||||
}
|
||||
|
||||
if(report.Result == CommunicationResult.ConnectOK)
|
||||
{
|
||||
// fill the DASInfo
|
||||
var SliceInfoOK = sliceHandler.QueryInformation(newDev);
|
||||
|
||||
// add it to our list
|
||||
lock(ConnectedDevicesLock)
|
||||
{
|
||||
ConnectedDevices.Add(newDev);
|
||||
}
|
||||
|
||||
// notify our subscribers
|
||||
if(!SliceInfoOK)
|
||||
{
|
||||
factory.ReportFailed();
|
||||
}
|
||||
else
|
||||
{
|
||||
factory.ReportArrived();
|
||||
}
|
||||
}
|
||||
else if(report.Result == CommunicationResult.DisconnectOK)
|
||||
{
|
||||
// first dispose of it
|
||||
newDev.Dispose();
|
||||
|
||||
// remove it from our list
|
||||
lock(ConnectedDevicesLock)
|
||||
{
|
||||
ConnectedDevices.Remove(newDev);
|
||||
}
|
||||
|
||||
// notify our subscribers
|
||||
factory.ReportRemoved();
|
||||
}
|
||||
else
|
||||
{
|
||||
// first dispose of it
|
||||
newDev.Dispose();
|
||||
|
||||
factory.ReportFailed();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
*/
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user