390 lines
12 KiB
C#
390 lines
12 KiB
C#
using EonaCat.HID.Helpers;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.Drawing;
|
|
using System.Globalization;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Windows.Forms;
|
|
|
|
namespace EonaCat.HID.Analyzer
|
|
{
|
|
public partial class MainForm : Form
|
|
{
|
|
private const int WriteReportTimeout = 3000;
|
|
|
|
private Device _device;
|
|
private List<Device> _deviceList;
|
|
|
|
public MainForm()
|
|
{
|
|
InitializeComponent();
|
|
}
|
|
|
|
private void MainForm_Load(object sender, EventArgs e)
|
|
{
|
|
try
|
|
{
|
|
rtbEventLog.Font = new Font("Consolas", 9);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
PopupException(ex.Message);
|
|
}
|
|
}
|
|
|
|
private void MainForm_Shown(object sender, EventArgs e)
|
|
{
|
|
try
|
|
{
|
|
_deviceList = Devices.Enumerate().ToList();
|
|
UpdateDeviceList();
|
|
toolStripStatusLabel1.Text = "Please select device and click open to start.";
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
PopupException(ex.Message);
|
|
}
|
|
}
|
|
|
|
private void AppendEventLog(string result, Color? color = null, bool appendNewLine = true)
|
|
{
|
|
var currentColor = color ?? Color.Black;
|
|
if (appendNewLine)
|
|
{
|
|
result += Environment.NewLine;
|
|
}
|
|
|
|
// update from UI thread
|
|
Invoke(new MethodInvoker(() =>
|
|
{
|
|
rtbEventLog.SelectionStart = rtbEventLog.TextLength;
|
|
rtbEventLog.SelectionLength = 0;
|
|
rtbEventLog.SelectionColor = currentColor;
|
|
rtbEventLog.AppendText(result);
|
|
|
|
if (!rtbEventLog.Focused)
|
|
{
|
|
rtbEventLog.ScrollToCaret();
|
|
}
|
|
}));
|
|
}
|
|
|
|
private void UpdateDeviceList()
|
|
{
|
|
dataGridView1.SelectionChanged -= DataGridView1_SelectionChanged;
|
|
dataGridView1.Rows.Clear();
|
|
|
|
for (int i = 0; i < _deviceList.Count; i++)
|
|
{
|
|
Device device = _deviceList[i];
|
|
|
|
var deviceName = "";
|
|
var deviceManufacturer = "";
|
|
var deviceSerialNumber = "";
|
|
|
|
var info = device.Info;
|
|
var capabilities = device.Capabilities;
|
|
|
|
deviceName = device.ReadProductName();
|
|
deviceManufacturer = device.ReadManufacturer();
|
|
deviceSerialNumber = device.ReadSerialNumber();
|
|
|
|
var row = new string[]
|
|
{
|
|
(i + 1).ToString(),
|
|
deviceName,
|
|
deviceManufacturer,
|
|
deviceSerialNumber,
|
|
capabilities.InputReportByteLength.ToString(),
|
|
capabilities.OutputReportByteLength.ToString(),
|
|
capabilities.FeatureReportByteLength.ToString(),
|
|
$"Vendor:{info.VendorId:X4} Product:{info.ProductId:X4} Revision:{info.Version:X4}",
|
|
device.DevicePath
|
|
};
|
|
dataGridView1.Rows.Add(row);
|
|
}
|
|
dataGridView1.SelectionChanged += DataGridView1_SelectionChanged;
|
|
DataGridView1_SelectionChanged(this, null);
|
|
}
|
|
|
|
private void PopupException(string message, string caption = "Exception")
|
|
{
|
|
Invoke(new Action(() =>
|
|
{
|
|
MessageBox.Show(message, caption, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
}));
|
|
}
|
|
|
|
private void NewToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
try
|
|
{
|
|
Process.Start(Assembly.GetExecutingAssembly().Location);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
PopupException(ex.Message);
|
|
}
|
|
}
|
|
|
|
private void ExitToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
try
|
|
{
|
|
this.Close();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
PopupException(ex.Message);
|
|
}
|
|
}
|
|
|
|
private void AboutToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
try
|
|
{
|
|
HelpToolStripButton_Click(sender, e);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
PopupException(ex.Message);
|
|
}
|
|
}
|
|
|
|
private void ToolStripButtonReload_Click(object sender, EventArgs e)
|
|
{
|
|
try
|
|
{
|
|
_deviceList = Devices.Enumerate().ToList();
|
|
UpdateDeviceList();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
PopupException(ex.Message);
|
|
}
|
|
}
|
|
|
|
private void ToolStripButtonFilter_Click(object sender, EventArgs e)
|
|
{
|
|
try
|
|
{
|
|
var str = toolStripTextBoxVidPid.Text.Split(':');
|
|
var vid = int.Parse(str[0], NumberStyles.AllowHexSpecifier);
|
|
var pid = int.Parse(str[1], NumberStyles.AllowHexSpecifier);
|
|
_deviceList = Devices.Enumerate(vid, pid).ToList();
|
|
UpdateDeviceList();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
PopupException(ex.Message);
|
|
}
|
|
}
|
|
|
|
private void ToolStripButtonConnect_Click(object sender, EventArgs e)
|
|
{
|
|
ConnectToSelectedDevice();
|
|
}
|
|
|
|
private void ConnectToSelectedDevice()
|
|
{
|
|
try
|
|
{
|
|
_device = _deviceList[dataGridView1.SelectedRows[0].Index];
|
|
if (_device == null)
|
|
{
|
|
throw new Exception("Could not find Hid USB Device with specified VID PID");
|
|
}
|
|
|
|
// Open a device for reading and writing
|
|
_device.OpenDevice(DeviceMode.Overlapped, DeviceMode.Overlapped, ShareMode.ShareRead | ShareMode.ShareWrite);
|
|
_device.OnInserted += HidDevice_Inserted;
|
|
_device.OnRemoved += HidDevice_Removed;
|
|
_device.MonitorDeviceEvents = true;
|
|
AppendEventLog($"Connected to device {_device.ReadProductName()}", Color.Green);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
PopupException(ex.Message);
|
|
}
|
|
}
|
|
|
|
private void ToolStripButtonClear_Click(object sender, EventArgs e)
|
|
{
|
|
try
|
|
{
|
|
rtbEventLog.Clear();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
PopupException(ex.Message);
|
|
}
|
|
}
|
|
|
|
private void HelpToolStripButton_Click(object sender, EventArgs e)
|
|
{
|
|
try
|
|
{
|
|
var aboutbox = new AboutBox();
|
|
aboutbox.ShowDialog();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
PopupException(ex.Message);
|
|
}
|
|
}
|
|
|
|
private void ButtonReadInput_Click(object sender, EventArgs e)
|
|
{
|
|
try
|
|
{
|
|
var len = _device.Capabilities.InputReportByteLength;
|
|
if (len <= 0)
|
|
{
|
|
throw new Exception("This device has no Input Report support!");
|
|
}
|
|
|
|
_device.ReadReport(Device_InputReportReceived);
|
|
AppendEventLog("Hid Input Report Callback Started.");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
PopupException(ex.Message);
|
|
}
|
|
}
|
|
|
|
private void ButtonWriteOutput_Click(object sender, EventArgs e)
|
|
{
|
|
try
|
|
{
|
|
var hidReportId = byte.Parse(comboBoxReportId.Text);
|
|
var buf = ByteHelper.HexStringToByteArray(textBoxWriteData.Text);
|
|
|
|
var report = _device.CreateReport();
|
|
if (buf.Length > report.Data.Length)
|
|
{
|
|
throw new Exception("Output Report Length Exceed");
|
|
}
|
|
|
|
report.ReportId = hidReportId;
|
|
Array.Copy(buf, report.Data, buf.Length);
|
|
_device.WriteReport(report, WriteReportTimeout);
|
|
var str = string.Format("Tx Output Report [{0}] --> ID:{1}, {2}", report.Data.Length + 1, report.ReportId, ByteHelper.ByteArrayToHexString(report.Data));
|
|
AppendEventLog(str, Color.DarkGreen);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
PopupException(ex.Message);
|
|
}
|
|
}
|
|
|
|
private void ButtonReadFeature_Click(object sender, EventArgs e)
|
|
{
|
|
try
|
|
{
|
|
var hidReportId = byte.Parse(comboBoxReportId.Text);
|
|
var len = _device.Capabilities.FeatureReportByteLength;
|
|
if (len <= 0)
|
|
{
|
|
throw new Exception("This device has no Feature Report support!");
|
|
}
|
|
|
|
_device.ReadFeatureData(out byte[] buf, hidReportId);
|
|
var str = string.Format("Rx Feature Report [{0}] <-- {1}", buf.Length, ByteHelper.ByteArrayToHexString(buf));
|
|
AppendEventLog(str, Color.Blue);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
PopupException(ex.Message);
|
|
}
|
|
}
|
|
|
|
private void ButtonWriteFeature_Click(object sender, EventArgs e)
|
|
{
|
|
try
|
|
{
|
|
var hidReportId = byte.Parse(comboBoxReportId.Text);
|
|
var buf = ByteHelper.HexStringToByteArray(textBoxWriteData.Text);
|
|
|
|
var len = _device.Capabilities.FeatureReportByteLength;
|
|
if (buf.Length > len)
|
|
{
|
|
throw new Exception("Write Feature Report Length Exceed");
|
|
}
|
|
|
|
Array.Resize(ref buf, len);
|
|
_device.WriteFeatureData(buf);
|
|
var str = string.Format("Tx Feature Report [{0}] --> {1}", buf.Length, ByteHelper.ByteArrayToHexString(buf));
|
|
AppendEventLog(str, Color.DarkGreen);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
PopupException(ex.Message);
|
|
}
|
|
}
|
|
|
|
private void DataGridView1_SelectionChanged(object sender, EventArgs e)
|
|
{
|
|
try
|
|
{
|
|
if (dataGridView1.SelectedRows.Count <= 0) return;
|
|
var index = dataGridView1.SelectedRows[0].Index;
|
|
|
|
var devinfo = _deviceList[index].Info;
|
|
toolStripTextBoxVidPid.Text = string.Format("{0:X4}:{1:X4}", devinfo.VendorId, devinfo.ProductId);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
PopupException(ex.Message);
|
|
}
|
|
}
|
|
|
|
private void HidDevice_Inserted()
|
|
{
|
|
try
|
|
{
|
|
var str = string.Format("Inserted Device --> VID {0:X4}, PID {0:X4}", _device.Info.VendorId, _device.Info.ProductId);
|
|
AppendEventLog(str, Color.Orange);
|
|
_device.ReadReport(Device_InputReportReceived);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
PopupException(ex.Message);
|
|
}
|
|
}
|
|
|
|
private void HidDevice_Removed()
|
|
{
|
|
try
|
|
{
|
|
var str = string.Format("Removed Device --> VID {0:X4}, PID {0:X4}", _device.Info.VendorId, _device.Info.ProductId);
|
|
AppendEventLog(str);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
PopupException(ex.Message);
|
|
}
|
|
}
|
|
|
|
private void Device_InputReportReceived(Report report)
|
|
{
|
|
try
|
|
{
|
|
if (!_device.IsConnected || !_device.IsOpen || report.Data == null) return;
|
|
var str = $"Rx Input Report [{report.Data.Length + 1}] <-- ID:{report.ReportId}, {ByteHelper.ByteArrayToHexString(report.Data)}";
|
|
AppendEventLog(str, Color.Blue);
|
|
_device.ReadReport(Device_InputReportReceived);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
PopupException(ex.Message);
|
|
}
|
|
}
|
|
|
|
private void dataGridView1_DoubleClick(object sender, EventArgs e)
|
|
{
|
|
ConnectToSelectedDevice();
|
|
}
|
|
}
|
|
} |