Files
DP44/Common/DTS.Common.IConnection/.svn/pristine/45/45885bbd967639f04eaa155056548d9d68e1b402.svn-base
2026-04-17 14:55:32 -04:00

486 lines
20 KiB
Plaintext

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Runtime.InteropServices;
using DTS.DASLib.Connection.USBFramework;
using DTS.DASLib.DASResource;
namespace DTS.DASLib.Connection
{
public class HIDUSBConnection: IConnection
{
public double GetCurrentDownloadRate() { return 0D; }
public double GetCurrentUploadRate() { return 0D; }
public const int HIDSLICE_PID = 0x0003;
public const int DTS_VID = 0x1CB9;
protected bool _Connected;
protected int NumberOfInputBuffers = 0;
protected int _HIDHandle;
protected bool _MyDeviceDetected;
protected HIDevice _MyHID = new HIDevice();
protected int _ReadHandle;
protected int _WriteHandle;
protected byte[] InputReportBuffer;
protected FileIODeclarations.SECURITY_ATTRIBUTES Security;
protected string Device_Name;
private bool disposed;
public event EventHandler OnDisconnected;
public bool Connected { get { return _Connected; } }
public string ConnectString { get { return Device_Name; } }
public System.Net.Sockets.SocketFlags Flags { get; set; }
public string GetConnectionData() { return ""; }
public void Create(string ConnectString)
{
Device_Name = ConnectString;
}
~HIDUSBConnection()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if(disposed)
return;
if(disposing)
{
try
{
FileIODeclarations.CloseHandle(_HIDHandle);
}
catch { }
try
{
FileIODeclarations.CloseHandle(_ReadHandle);
}
catch { }
try
{
FileIODeclarations.CloseHandle(_WriteHandle);
}
catch { }
_MyHID.Dispose();
_Connected = false;
}
disposed = true;
}
public IAsyncResult BeginDisconnect(bool reuseSocket,
AsyncCallback cb,
Object state)
{
HIDUSBRecAsyncResult rar = new HIDUSBRecAsyncResult();
rar.AsyncState = state;
rar.AsyncWaitHandle = new ManualResetEvent(false);
rar.CompletedSynchronously = false;
rar.IsCompleted = false;
rar.buffer = null;
rar.offset = 0;
rar.size = 0;
if(!ThreadPool.QueueUserWorkItem(NetCallbackFix, new AUSBRecFix(cb, rar)))
{
// "HIDUSBConnection.BeginDisconnect: Unable to enqueue function"
throw new System.Exception(Strings.HIDUSBConnection_BeginDisconnect_Err1);
}
return rar;
}
public void EndDisconnect(IAsyncResult asyncResult)
{
int Result;
Result = FileIODeclarations.CloseHandle(_HIDHandle);
Result = FileIODeclarations.CloseHandle(_ReadHandle);
Result = FileIODeclarations.CloseHandle(_WriteHandle);
_Connected = false;
}
public IAsyncResult BeginAccept(AsyncCallback callback,
Object state)
{
throw new NotSupportedException();
}
public IConnection EndAccept(IAsyncResult asyncResult)
{
throw new NotSupportedException();
}
public void Bind(int port)
{
throw new NotSupportedException();
}
public void Listen(int backlog)
{
throw new NotSupportedException();
}
// Define a class of delegates that point to the Hid.DeviceReport.Read function.
// The delegate has the same parameters as Hid.DeviceReport.Read.
// Used for asynchronous reads from the device.
protected delegate void ReadInputReportDelegate(int readHandle,
int hidHandle,
int writeHandle,
ref bool myDeviceDetected,
ref byte[] readBuffer,
ref bool success);
private class AUSBRecFix
{
public AsyncCallback cb;
public HIDUSBRecAsyncResult res;
public AUSBRecFix(AsyncCallback _cb, HIDUSBRecAsyncResult _res)
{
cb = _cb;
res = _res;
}
}
public HIDUSBConnection()
{
disposed = false;
Security = new FileIODeclarations.SECURITY_ATTRIBUTES();
Security.lpSecurityDescriptor = 0;
Security.bInheritHandle = System.Convert.ToInt32(true);
Security.nLength = Marshal.SizeOf(Security);
_Connected = false;
}
public IAsyncResult BeginConnect(AsyncCallback cb, object state)
{
HIDUSBRecAsyncResult rar = new HIDUSBRecAsyncResult();
rar.AsyncState = state;
rar.AsyncWaitHandle = new ManualResetEvent(false);
rar.CompletedSynchronously = false;
rar.IsCompleted = false;
rar.buffer = null;
rar.offset = 0;
rar.size = 0;
if(!ThreadPool.QueueUserWorkItem(NetCallbackFix, new AUSBRecFix(cb, rar)))
{
// "USBConnection.BeginConnect: Unable to enqueue function"
throw new System.Exception(Strings.USBConnection_BeginConnect_Err1);
}
return rar;
}
private void NetCallbackFix(object obj)
{
try
{
AUSBRecFix ausbrf = obj as AUSBRecFix;
ausbrf.cb(ausbrf.res);
}
catch(System.Exception ex)
{
System.Windows.Forms.MessageBox.Show("HIDUSBConnection.NetCallbackFix: Exception " + ex.Message + " " + ex.StackTrace);
}
}
public static string GetFirstConnectString()
{
#region Hack to connect just one recorder by manually finding the first one ...
int Result;
int _HIDHandle;
HIDevice _MyHID = new HIDevice();
FileIODeclarations.SECURITY_ATTRIBUTES Security;
Security = new FileIODeclarations.SECURITY_ATTRIBUTES();
Security.lpSecurityDescriptor = 0;
Security.bInheritHandle = System.Convert.ToInt32(true);
Security.nLength = Marshal.SizeOf(Security);
System.Guid HIDGuid = new Guid();
string GuidString;
string[] DevicePathName = new string[128];
HIDDeclarations.HidD_GetHidGuid(ref HIDGuid);
GuidString = HIDGuid.ToString();
DeviceManagement _MyDeviceManagement = new DeviceManagement();
bool DeviceFound = _MyDeviceManagement.FindDeviceFromGuid(HIDGuid, ref DevicePathName);
if (true == DeviceFound)
{
int MemberIndex = 0;
DeviceFound = false;
do
{
//GRV - this works and is a true copy of Axelson
_HIDHandle = FileIODeclarations.CreateFile(DevicePathName[MemberIndex],
0,
FileIODeclarations.FILE_SHARE_READ | FileIODeclarations.FILE_SHARE_WRITE,
ref Security, FileIODeclarations.OPEN_EXISTING, 0, 0);
if (_HIDHandle != FileIODeclarations.INVALID_HANDLE_VALUE)
{
// The returned handle is valid,
// so find out if this is the device we're looking for.
// Set the Size property of DeviceAttributes to the number of bytes in the structure.
//_MyHID.DeviceAttributes.Size = _MyHID.DeviceAttributes.ToString().Length;
_MyHID.DeviceAttributes.Size = Marshal.SizeOf(_MyHID.DeviceAttributes);
// ***
// API function:
// HidD_GetAttributes
// Purpose:
// Retrieves a HIDD_ATTRIBUTES structure containing the Vendor ID,
// Product ID, and Product Version Number for a device.
// Accepts:
// A handle returned by CreateFile.
// A pointer to receive a HIDD_ATTRIBUTES structure.
// Returns:
// True on success, False on failure.
// ***
Result = HIDDeclarations.HidD_GetAttributes(_HIDHandle, ref _MyHID.DeviceAttributes);
if (Result != 0)
{
// Find out if the device matches the one we're looking for.
if (_MyHID.DeviceAttributes.VendorID == DTS_VID &&
_MyHID.DeviceAttributes.ProductID == HIDSLICE_PID)
{
// It's the desired device.
DeviceFound = true;
// Close the device so it can be opened for real later
Result = FileIODeclarations.CloseHandle(_HIDHandle);
// return the device's name
return DevicePathName[MemberIndex];
}
else
{
// It's not a match, so close the handle.
DeviceFound = false;
Result = FileIODeclarations.CloseHandle(_HIDHandle);
}
}
else
{
// There was a problem in retrieving the information.
DeviceFound = false;
Result = FileIODeclarations.CloseHandle(_HIDHandle);
}
}
// Keep looking until we find the device or there are no more left to examine.
MemberIndex = MemberIndex + 1;
} while (!((DeviceFound == true) || (MemberIndex == DevicePathName.Length)));
}
return string.Empty;
#endregion // Hack to connect just one recorder by manually finding the first one ...
}
public void EndConnect(IAsyncResult ar)
{
int Result;
_HIDHandle = FileIODeclarations.CreateFile(ConnectString,
0,
FileIODeclarations.FILE_SHARE_READ | FileIODeclarations.FILE_SHARE_WRITE,
ref Security,
FileIODeclarations.OPEN_EXISTING,
0,
0);
if(_HIDHandle == FileIODeclarations.INVALID_HANDLE_VALUE)
{
// "HIDUSBConnection.EndConnect: Can't open {0} in Connect"
throw new System.Exception(string.Format(Strings.HIDUSBConnection_EndConnect_Err1, ConnectString));
}
// Set the Size property of DeviceAttributes to the number of bytes in the structure.
_MyHID.DeviceAttributes.Size = Marshal.SizeOf(_MyHID.DeviceAttributes);
// HidD_GetAttributes
// Purpose: Retrieves a HIDD_ATTRIBUTES structure containing the Vendor ID,
// Product ID, and Product Version Number for a device.
// Accepts: A handle returned by CreateFile.
// A pointer to receive a HIDD_ATTRIBUTES structure.
// Returns: True on success, False on failure.
Result = HIDDeclarations.HidD_GetAttributes(_HIDHandle, ref _MyHID.DeviceAttributes);
// Learn the capabilities of the device.
_MyHID.Capabilities = _MyHID.GetDeviceCapabilities(_HIDHandle);
//Find out if device is system mouse or keyboard //GRV
string HIDUsage = _MyHID.GetHIDUsage(_MyHID.Capabilities);
// Get and display the Input report buffer size.
GetInputReportBufferSize();
// Get another handle to use in overlapped ReadFiles (for requesting Input reports).
_ReadHandle = FileIODeclarations.CreateFile(ConnectString,
FileIODeclarations.GENERIC_READ,
FileIODeclarations.FILE_SHARE_READ | FileIODeclarations.FILE_SHARE_WRITE,
ref Security,
FileIODeclarations.OPEN_EXISTING,
0,
0);
_WriteHandle = FileIODeclarations.CreateFile(ConnectString,
FileIODeclarations.GENERIC_WRITE,
FileIODeclarations.FILE_SHARE_READ | FileIODeclarations.FILE_SHARE_WRITE,
ref Security,
FileIODeclarations.OPEN_EXISTING,
0,
0);
// (optional)
// Flush any waiting reports in the input buffer.
_MyHID.FlushQueue(_ReadHandle);
HIDevice.InputReport myInputReport = new HIDevice.InputReport();
// Define a delegate for the Read method of myInputReport.
ReadInputReportDelegate MyReadInputReportDelegate = new ReadInputReportDelegate(myInputReport.Read);
// Set the size of the Input report buffer.
InputReportBuffer = new byte[_MyHID.Capabilities.InputReportByteLength];
_Connected = true;
}
protected void GetInputReportBufferSize()
{
try
{
// Get the number of input buffers.
_MyHID.GetNumberOfInputBuffers(_HIDHandle, ref NumberOfInputBuffers);
}
catch(System.Exception ex)
{
// "HIDUSBConnection.GetInputReportBufferSize: Error during {0}"
throw new ApplicationException(string.Format(Strings.HIDUSBConnection_GetInputReportBufferSize_Err1, ex.Message));
}
}
public class HIDUSBRecAsyncResult: IAsyncResult
{
public object AsyncState { get; set; }
public WaitHandle AsyncWaitHandle { get; set; }
public bool CompletedSynchronously { get; set; }
public bool IsCompleted { get; set; }
public byte[] buffer { get; set; }
public int offset { get; set; }
public int size { get; set; }
}
public IAsyncResult BeginSend(byte[] buffer, int offset, int size,
AsyncCallback cb, object state)
{
if(_ReadHandle == FileIODeclarations.INVALID_HANDLE_VALUE || _WriteHandle == FileIODeclarations.INVALID_HANDLE_VALUE)
{
// "HIDUSBConnection.BeginSend: Invalid read or write handle"
throw new System.Exception(Strings.HIDUSBConnection_BeginSend_Err1);
}
HIDUSBRecAsyncResult rar = new HIDUSBRecAsyncResult();
rar.AsyncState = state;
rar.AsyncWaitHandle = new ManualResetEvent(false);
rar.CompletedSynchronously = false;
rar.IsCompleted = false;
rar.buffer = buffer;
rar.offset = offset;
rar.size = size;
if(!ThreadPool.QueueUserWorkItem(NetCallbackFix, new AUSBRecFix(cb, rar)))
{
// "HIDUSBConnection.BeginSend: Unable to enqueue function"
throw new System.Exception(Strings.HIDUSBConnection_BeginSend_Err2);
}
return rar;
}
public int EndSend(IAsyncResult ar)
{
HIDUSBRecAsyncResult rar = ar as HIDUSBRecAsyncResult;
int bytesLeft = rar.size;
int maxOutputReportLength = _MyHID.Capabilities.OutputReportByteLength;
byte[] OutputReportBuffer = new byte[maxOutputReportLength];
OutputReportBuffer[0] = 0;
for(int i = 0; i < rar.size; i += (maxOutputReportLength - 1))
{
bytesLeft = rar.size - i;
int bytesToCopy = ((bytesLeft < OutputReportBuffer.Length - 1) ? bytesLeft : OutputReportBuffer.Length - 1);
Buffer.BlockCopy(rar.buffer, rar.offset + i, OutputReportBuffer, 1, bytesToCopy);
HIDevice.OutputReport myOutputReport = new HIDevice.OutputReport();
if(!myOutputReport.Write(OutputReportBuffer, _WriteHandle))
{
// "HIDUSBConnection.EndSend: Error writing report"
throw new System.Exception(Strings.HIDUSBConnection_EndSend_Err1);
}
}
return rar.size;
}
public IAsyncResult BeginReceive(byte[] buffer, int offset, int size,
AsyncCallback cb, object state)
{
if(_ReadHandle == FileIODeclarations.INVALID_HANDLE_VALUE || _WriteHandle == FileIODeclarations.INVALID_HANDLE_VALUE)
{
// "HIDUSBConnection.BeginReceive: Invalid read or write handle"
throw new System.Exception(Strings.HIDUSBConnection_BeginReceive_Err1);
}
HIDUSBRecAsyncResult rar = new HIDUSBRecAsyncResult();
rar.AsyncState = state;
rar.AsyncWaitHandle = new ManualResetEvent(false);
rar.CompletedSynchronously = false;
rar.IsCompleted = false;
rar.buffer = buffer;
rar.offset = offset;
rar.size = size;
if(!ThreadPool.QueueUserWorkItem(NetCallbackFix, new AUSBRecFix(cb, rar)))
{
// "HIDUSBConnection.BeginReceive: Unable to enqueue function"
throw new System.Exception(Strings.HIDUSBConnection_BeginReceive_Err2);
}
return rar;
}
public int EndReceive(IAsyncResult ar)
{
HIDUSBRecAsyncResult rar = ar as HIDUSBRecAsyncResult;
bool Success = false;
HIDevice.InputReport myInputReport = new HIDevice.InputReport();
//byte[] InputBuffer = new byte[rar.size+1];
myInputReport.Read(_ReadHandle, _HIDHandle, _WriteHandle, ref _MyDeviceDetected, ref InputReportBuffer, ref Success);
if(Success)
{
Buffer.BlockCopy(InputReportBuffer, 1, rar.buffer, rar.offset, InputReportBuffer.Length - 1);
rar.IsCompleted = true;
((ManualResetEvent)rar.AsyncWaitHandle).Set();
return rar.size;
}
((ManualResetEvent)rar.AsyncWaitHandle).Set();
return 0;
}
}
}