public DetailsForm(HidDevice dev) { InitializeComponent(); if (dev == null || dev.IsInvalid) { Close(); return; } lblProdName.Text += " " + dev.Product; lblVendName.Text += " " + dev.Manufacturer; lblSerialNum.Text += " " + dev.SerialNumber; Hid.HiddAttributes att = dev.Attributes; lblVid.Text += " " + att.VendorId.ToString("X4"); lblPid.Text += " " + att.ProductId.ToString("X4"); lblRev.Text += " " + att.VersionNumber.ToString("X4"); Hid.HidpCaps caps = dev.Capabilities; lblInputSize.Text += " " + caps.InputReportByteLength + " bytes"; lblOutputSize.Text += " " + caps.OutputReportByteLength + " bytes"; lblFeatureSize.Text += " " + caps.FeatureReportByteLength + " bytes"; listBoxValueCaps.DisplayMember = "Text"; foreach (var inCap in dev.InputValueCaps) { AddValueCap(inCap, "Input Report"); } foreach (var outCap in dev.OutputValueCaps) { AddValueCap(outCap, "Output Report"); } foreach (var featCap in dev.FeatureValueCaps) { AddValueCap(featCap, "Feature Report"); } for (uint i = 1; i < 255; i++) { string str = dev.GetIndexedString(i); if (!string.IsNullOrEmpty(str)) { listBoxStrings.Items.Add(i.ToString() + ": " + str); } else { break; //HACK Logitech G105 keyboard crashes unless this is here } } }
private void devicesListView_SelectedIndexChanged(object sender, EventArgs e) { if (backgroundReadToolStripMenuItem.Checked) { if (!CancelBackgroundWorkerAndWait(readThread)) { return; } } if (devicesListView.SelectedIndices.Count == 0) { return; } if (currentDevice != null) { currentDevice.Dispose(); currentDevice = null; } lastSelectedDevice = (string)devicesListView.SelectedItems[0].Tag; currentDevice = new HidDevice(lastSelectedDevice); if (currentDevice.IsInvalid) { currentDevice.Dispose(); currentDevice = null; } Hid.HidpCaps caps = currentDevice.Capabilities; int numBytes = caps.InputReportByteLength; numBytes = Math.Max(numBytes, caps.OutputReportByteLength); numBytes = Math.Max(numBytes, caps.FeatureReportByteLength); numBytes -= 1; //first byte is always report id, for (int i = 0; i < byteTextboxes.Length; i++) { byteTextboxes[i].Visible = (i < numBytes); } inBuffer = new byte[caps.InputReportByteLength]; outBuffer = new byte[caps.OutputReportByteLength]; featureBuffer = new byte[caps.FeatureReportByteLength]; btnRead.Enabled = (caps.InputReportByteLength != 0); btnWrite.Enabled = (caps.OutputReportByteLength != 0); btnGetReport.Enabled = (caps.InputReportByteLength != 0); btnSetReport.Enabled = (caps.OutputReportByteLength != 0); btnGetFeature.Enabled = (caps.FeatureReportByteLength != 0); btnSetFeature.Enabled = (caps.FeatureReportByteLength != 0); numPackets = 0; numTimeouts = 0; toolStripTimeouts.Text = "Timeouts: 0/0"; if (backgroundReadToolStripMenuItem.Checked && caps.InputReportByteLength != 0) { readThread.RunWorkerAsync(currentDevice); } }
public HidDevice(string path) { //device mutex lockObject = new object(); //static buffers strBuffer = new StringBuilder(256); //open device //TODO why is 0x40000000 missing from FileAttribute in PInvoke? reference = Kernel32.CreateFile(path, Kernel32.ACCESS_MASK.GenericRight.GENERIC_WRITE, Kernel32.FileShare.FILE_SHARE_READ | Kernel32.FileShare.FILE_SHARE_WRITE, IntPtr.Zero, Kernel32.CreationDisposition.OPEN_EXISTING, Kernel32.CreateFileFlags.FILE_FLAG_OVERLAPPED, Kernel32.SafeObjectHandle.Null); if (reference.IsInvalid) { return; } //overlapped fileEvent = new ManualResetEvent(false); fileOverlapped = new SafeOverlapped(fileEvent); //get preparsed data if (!Hid.HidD_GetPreparsedData(reference, out preparsedData)) { return; } //transfer buffers capabilities = Hid.HidP_GetCaps(preparsedData); inBuffer = new byte[capabilities.InputReportByteLength]; outBuffer = new byte[capabilities.OutputReportByteLength]; featureBuffer = new byte[capabilities.FeatureReportByteLength]; //dynamic caps inputValueCaps = new List <ValueCaps>(); outputValueCaps = new List <ValueCaps>(); featureValueCaps = new List <ValueCaps>(); ushort numInputCaps = capabilities.NumberInputValueCaps; ushort numOutputCaps = capabilities.NumberOutputValueCaps; ushort numFeatureCaps = capabilities.NumberFeatureValueCaps; ushort maxValueCaps = Math.Max(numInputCaps, numOutputCaps); maxValueCaps = Math.Max(maxValueCaps, numFeatureCaps); int valueCapSize = Marshal.SizeOf <ValueCaps>(); IntPtr valueCapPtr = Marshal.AllocHGlobal(maxValueCaps * valueCapSize); HidPStatus stat = Hid.HidP_GetValueCaps(ReportType.Input, valueCapPtr, ref numInputCaps, preparsedData); for (int i = 0; i < numInputCaps; i++) { ValueCaps val = Marshal.PtrToStructure <ValueCaps>(new IntPtr(valueCapPtr.ToInt64() + (i * valueCapSize))); inputValueCaps.Add(val); } stat = Hid.HidP_GetValueCaps(ReportType.Output, valueCapPtr, ref numOutputCaps, preparsedData); for (int i = 0; i < numOutputCaps; i++) { ValueCaps val = Marshal.PtrToStructure <ValueCaps>(new IntPtr(valueCapPtr.ToInt64() + i * valueCapSize)); outputValueCaps.Add(val); } stat = Hid.HidP_GetValueCaps(ReportType.Feature, valueCapPtr, ref numFeatureCaps, preparsedData); for (int i = 0; i < numFeatureCaps; i++) { ValueCaps val = Marshal.PtrToStructure <ValueCaps>(new IntPtr(valueCapPtr.ToInt64() + i * valueCapSize)); featureValueCaps.Add(val); } Marshal.FreeHGlobal(valueCapPtr); }