public static bool WriteRawReportToDevice(byte[] outputReportBuffer, ref DeviceInformationStructure deviceInformation) { // Make sure a device is attached if (!deviceInformation.IsDeviceAttached) { return(false); } var numberOfBytesWritten = 0; try { // Set an output report via interrupt to the device var success = Kernel32.WriteFile( deviceInformation.WriteHandle, outputReportBuffer, outputReportBuffer.Length, ref numberOfBytesWritten, IntPtr.Zero); return(success); } catch (Exception) { // An error - send out some debug and return failure return(false); } }
public static bool WriteRawReportToDevice(byte[] outputReportBuffer, ref DeviceInformationStructure deviceInformation) { // Make sure a device is attached if (!deviceInformation.IsDeviceAttached) { Debug.WriteLine("usbGenericHidCommunication:writeReportToDevice(): -> No device attached!"); return(false); } var numberOfBytesWritten = 0; try { // Set an output report via interrupt to the device var success = Kernel32.WriteFile( deviceInformation.WriteHandle, outputReportBuffer, outputReportBuffer.Length, ref numberOfBytesWritten, IntPtr.Zero); Debug.WriteLine(success ? "usbGenericHidCommunication:writeReportToDevice(): -> Write report succeeded" : "usbGenericHidCommunication:writeReportToDevice(): -> Write report failed!"); return(success); } catch (Exception) { // An error - send out some debug and return failure Debug.WriteLine( "usbGenericHidCommunication:writeReportToDevice(): -> EXCEPTION: When attempting to send an output report"); return(false); } }
public static bool FindTargetDevice(ref DeviceInformationStructure deviceInformation) { deviceInformation.HidHandle = GetDeviceInformationHidHandle(deviceInformation.DevicePathName); deviceInformation.ReadHandle = GetDeviceInformationReadHandle(deviceInformation.DevicePathName); deviceInformation.WriteHandle = GetDeviceInformationWriteHandle(deviceInformation.DevicePathName); if (deviceInformation.HidHandle.IsInvalid || deviceInformation.ReadHandle.IsInvalid || deviceInformation.WriteHandle.IsInvalid) { return(false); } if (!GetAttributes(ref deviceInformation)) { return(false); } deviceInformation.DescriptorStrings = GetDescriptionStrings(deviceInformation.HidHandle); if (!QueryDeviceCapabilities(ref deviceInformation)) { return(false); } deviceInformation.IsDeviceAttached = true; return(true); }
private static bool FindHIDs(DeviceInformationStructure deviceInformation, List <string> InputList, ref List <string> FoundList) { List <SingleDevice> devices = FindDevices(deviceInformation); if (devices.Count > 0) { foreach (SingleDevice sdev in devices) { SingleHID singleHID = new SingleHID(sdev); foreach (string path in InputList) { Match match = Regex.Match(path, "VID_(.{4})", RegexOptions.IgnoreCase); ushort Vid; if (match.Success) { string vid_string = match.Groups[1].Value; Vid = ushort.Parse(vid_string, System.Globalization.NumberStyles.HexNumber); } else { Vid = 0; } match = Regex.Match(path, "PID_(.{4})", RegexOptions.IgnoreCase); ushort Pid; if (match.Success) { string pid_string = match.Groups[1].Value; Pid = ushort.Parse(pid_string, System.Globalization.NumberStyles.HexNumber); } else { Pid = 0; } match = Regex.Match(path, "MI_(.{2})", RegexOptions.IgnoreCase); ushort MI; if (match.Success) { string mi_string = match.Groups[1].Value; MI = ushort.Parse(mi_string, System.Globalization.NumberStyles.HexNumber); } else { MI = 0; } bool Detected = (Vid == singleHID.Vid) && (Pid == singleHID.Pid) && (MI == singleHID.MI); if (Detected) { FoundList.Add(path); //break; // Matching device found Debug.WriteLine("findTargetDevice() -> Device with matching VID and PID found!"); } } } } return(FoundList.Count > 0); }
private static bool InitSelectedHID(ref DeviceInformationStructure deviceInformation) { deviceInformation.IsDeviceAttached = false; // Query the HID device's capabilities (primarily we are only really interested in the // input and output report byte lengths as this allows us to validate information sent // to and from the device does not exceed the devices capabilities. // // We could determine the 'type' of HID device here too, but since this class is only // for generic HID communication we don't care... Debug.WriteLine("findTargetDevice() -> Performing CreateFile "); deviceInformation.HidHandle = Kernel32.CreateFile(deviceInformation.DevicePathName, 0, Constants.FileShareRead | Constants.FileShareWrite, IntPtr.Zero, Constants.OpenExisting, 0, 0); QueryDeviceCapabilities(ref deviceInformation); //deviceInformation.HidHandle.Close(); // Open the readHandle to the device Debug.WriteLine("findTargetDevice() -> Opening a readHandle to the device"); deviceInformation.ReadHandle = Kernel32.CreateFile( deviceInformation.DevicePathName, Constants.GenericRead, Constants.FileShareRead | Constants.FileShareWrite, IntPtr.Zero, Constants.OpenExisting, Constants.FileFlagOverlapped, 0); // Did we open the readHandle successfully? if (deviceInformation.ReadHandle.IsInvalid) { Debug.WriteLine("findTargetDevice() -> Unable to open a readHandle to the device!"); // deviceInformation.ReadHandle.Close(); deviceInformation.IsDeviceAttached = false; return(deviceInformation.IsDeviceAttached); } Debug.WriteLine("findTargetDevice() -> Opening a writeHandle to the device"); deviceInformation.WriteHandle = Kernel32.CreateFile( deviceInformation.DevicePathName, Constants.GenericWrite, Constants.FileShareRead | Constants.FileShareWrite, IntPtr.Zero, Constants.OpenExisting, 0, 0); // Did we open the writeHandle successfully? if (deviceInformation.WriteHandle.IsInvalid) { Debug.WriteLine("findTargetDevice() -> Unable to open a writeHandle to the device!"); // Attempt to close the writeHandle deviceInformation.WriteHandle.Close(); deviceInformation.IsDeviceAttached = false; return(deviceInformation.IsDeviceAttached); } // Device is now discovered and ready for use, update the status deviceInformation.IsDeviceAttached = true; return(deviceInformation.IsDeviceAttached); }
private static bool CheckDevice(DeviceInformationStructure dev1, SingleHID dev2) { bool Found = false; if (dev1.TargetCaption == dev2.Caption && dev1.TargetProductId == dev2.Pid && dev1.TargetVendorId == dev2.Vid && dev1.TargetMultiInterface == dev2.MI) { Found = true; } return(Found); }
private static List <SingleDevice> FindDevices(DeviceInformationStructure dev1) { List <SingleDevice> singleDevices = GetDeviceList(); List <SingleDevice> FoundDevices = new List <SingleDevice>(); foreach (SingleDevice dev2 in singleDevices) { if (CheckDevice(dev1, new SingleHID(dev2))) { FoundDevices.Add(dev2); } } return(FoundDevices); }
public static bool ReadSingleReportFromDevice(ref byte[] inputReportBuffer, ref DeviceInformationStructure deviceInformation) { var numberOfBytesRead = 0; // The size of our inputReportBuffer must be at least the same size as the input report. if (inputReportBuffer.Length != deviceInformation.Capabilities.InputReportByteLength) { // inputReportBuffer is not the right length! return(false); } // The readRawReportFromDevice method will fill the passed readBuffer or return false return(ReadRawReportFromDevice(ref inputReportBuffer, ref numberOfBytesRead, ref deviceInformation)); }
public static bool ReadSingleReportFromDevice(ref byte[] inputReportBuffer, ref DeviceInformationStructure deviceInformation) { var numberOfBytesRead = 0; // The size of our inputReportBuffer must be at least the same size as the input report. if (inputReportBuffer.Length != deviceInformation.Capabilities.InputReportByteLength) { // inputReportBuffer is not the right length! Debug.WriteLine( "usbGenericHidCommunication:readSingleReportFromDevice(): -> ERROR: The referenced inputReportBuffer size is incorrect for the input report size!"); return(false); } // The readRawReportFromDevice method will fill the passed readBuffer or return false return(ReadRawReportFromDevice(ref inputReportBuffer, ref numberOfBytesRead, ref deviceInformation)); }
private static bool GetAttributes(ref DeviceInformationStructure deviceInformation) { try { deviceInformation.Attributes.Size = Marshal.SizeOf(deviceInformation.Attributes); if (Hid.HidD_GetAttributes(deviceInformation.HidHandle, ref deviceInformation.Attributes)) { return(true); } } catch { Debug.WriteLine("GetAttributes failed"); return(false); } return(false); }
public static bool WriteRawReportToDevice(byte[] outputReportBuffer, ref DeviceInformationStructure deviceInformation) { // Make sure a device is attached if (!deviceInformation.IsDeviceAttached) { Debug.WriteLine("DeviceCommunication:writeReportToDevice(): -> 发送失败-设备未连接!"); return(false); } var numberOfBytesWritten = 0; try { var success = false; int sendCount = (int)Math.Ceiling(outputReportBuffer.Length / 8.0); for (int i = 0; i < sendCount; i++) { int surplusCount = outputReportBuffer.Length - i * 8; byte[] send = new byte[9]; send[0] = 255; int len = surplusCount >= 8 ? 8 : surplusCount; Array.Copy(outputReportBuffer, 8 * i, send, 1, len); success = Kernel32.WriteFile( deviceInformation.WriteHandle, send, deviceInformation.Capabilities.OutputReportByteLength, ref numberOfBytesWritten, IntPtr.Zero); } // Set an output report via interrupt to the device Debug.WriteLine(success ? "DeviceCommunication:writeReportToDevice(): -> 发送数据成功" : "DeviceCommunication:writeReportToDevice(): -> 发送失败!错误码:" + Marshal.GetLastWin32Error()); return(success); } catch (Exception ex) { // An error - send out some debug and return failure Debug.WriteLine("DeviceCommunication:writeReportToDevice(): -> 发生异常: " + ex.Message); return(false); } }
public static bool FindTargetDevices(ref DeviceInformationStructure deviceInformation, string Path = "") { Debug.WriteLine("findTargetDevice() -> Method called"); List <string> listOfDevicePathNames = new List <string>(); // 128 is the maximum number of USB devices allowed on a single host bool isDeviceDetected = false; List <string> DevicePaths = new List <string>(); try { bool deviceFoundByGuid = FindHidDevices(ref listOfDevicePathNames); // Get all the devices with the correct HID GUID if (deviceFoundByGuid) { isDeviceDetected = FindHIDs(deviceInformation, listOfDevicePathNames, ref DevicePaths); deviceInformation.Paths = DevicePaths; } if (Path == "") // take first { // Store the device's pathname in the device information deviceInformation.DevicePathName = DevicePaths[0]; } else { deviceInformation.DevicePathName = DevicePaths.Find(x => x.Equals(Path)); } // If we found a matching device // then open read and write handles to the device to allow communication if (isDeviceDetected) { InitSelectedHID(ref deviceInformation); } return(isDeviceDetected); } catch (Exception) { Debug.WriteLine("findTargetDevice() -> EXCEPTION: Unknown - device not found"); return(isDeviceDetected); } }
public static bool QueryDeviceCapabilities(ref DeviceInformationStructure deviceInformation) { var preparsedData = new IntPtr(); try { Hid.HidD_GetPreparsedData(deviceInformation.HidHandle, ref preparsedData); Hid.HidP_GetCaps(preparsedData, ref deviceInformation.Capabilities); } catch { Debug.WriteLine("QueryDeviceCapabilities failed with error {0}", Marshal.GetLastWin32Error()); return(false); } finally { // Free up the memory before finishing Hid.HidD_FreePreparsedData(preparsedData); } return(true); }
public static bool ReadRawReportFromDevice(ref byte[] inputReportBuffer, ref int numberOfBytesRead, ref DeviceInformationStructure deviceInformation) { // Make sure a device is attached if (!deviceInformation.IsDeviceAttached) { return(false); } IntPtr eventObject; var hidOverlapped = new NativeOverlapped(); IntPtr nonManagedBuffer; IntPtr nonManagedOverlapped; try { // Prepare an event object for the overlapped ReadFile eventObject = Kernel32.CreateEvent(IntPtr.Zero, false, false, ""); hidOverlapped.OffsetLow = 0; hidOverlapped.OffsetHigh = 0; hidOverlapped.EventHandle = eventObject; // Allocate memory for the unmanaged input buffer and overlap structure. nonManagedBuffer = Marshal.AllocHGlobal(inputReportBuffer.Length); nonManagedOverlapped = Marshal.AllocHGlobal(Marshal.SizeOf(hidOverlapped)); Marshal.StructureToPtr(hidOverlapped, nonManagedOverlapped, false); // Read the input report buffer var success = Kernel32.ReadFile( deviceInformation.ReadHandle, nonManagedBuffer, inputReportBuffer.Length, ref numberOfBytesRead, nonManagedOverlapped); if (!success) { // We are now waiting for the FileRead to complete // Wait a maximum of 3 seconds for the FileRead to complete var result = Kernel32.WaitForSingleObject(eventObject, 3000); switch (result) { // Has the ReadFile completed successfully? case Constants.WaitObject0: // Get the number of bytes transferred Kernel32.GetOverlappedResult(deviceInformation.ReadHandle, nonManagedOverlapped, ref numberOfBytesRead, false); break; // Did the FileRead operation timeout? case Constants.WaitTimeout: // Cancel the ReadFile operation Kernel32.CancelIo(deviceInformation.ReadHandle); if (!deviceInformation.HidHandle.IsInvalid) { deviceInformation.HidHandle.Close(); } if (!deviceInformation.ReadHandle.IsInvalid) { deviceInformation.ReadHandle.Close(); } if (!deviceInformation.WriteHandle.IsInvalid) { deviceInformation.WriteHandle.Close(); } // Detach the USB device to try to get us back in a known state //detachUsbDevice(); return(false); // Some other unspecified error has occurred? default: // Cancel the ReadFile operation // Detach the USB device to try to get us back in a known state return(false); } } // Report receieved correctly, copy the unmanaged input buffer over to the managed buffer Marshal.Copy(nonManagedBuffer, inputReportBuffer, 0, numberOfBytesRead); } catch (Exception) { // An error - send out some debug and return failure return(false); } // Release non-managed objects before returning Marshal.FreeHGlobal(nonManagedBuffer); Marshal.FreeHGlobal(nonManagedOverlapped); // Close the file handle to release the object Kernel32.CloseHandle(eventObject); return(true); }
public static bool ReadRawReportFromDeviceAsync(ref byte[] inputReportBuffer, ref int numberOfBytesRead, ref DeviceInformationStructure deviceInformation) { bool success; // Make sure a device is attached if (!deviceInformation.IsDeviceAttached) { return(false); } IntPtr eventObject; var hidOverlapped = new NativeOverlapped(); IntPtr nonManagedBuffer; IntPtr nonManagedOverlapped; try { // Prepare an event object for the overlapped ReadFile eventObject = Kernel32.CreateEvent(IntPtr.Zero, false, false, ""); hidOverlapped.OffsetLow = 0; hidOverlapped.OffsetHigh = 0; hidOverlapped.EventHandle = eventObject; // Allocate memory for the unmanaged input buffer and overlap structure. nonManagedBuffer = Marshal.AllocHGlobal(inputReportBuffer.Length); nonManagedOverlapped = Marshal.AllocHGlobal(Marshal.SizeOf(hidOverlapped)); Marshal.StructureToPtr(hidOverlapped, nonManagedOverlapped, false); // Read the input report buffer success = Kernel32.ReadFile( deviceInformation.ReadHandle, nonManagedBuffer, inputReportBuffer.Length, ref numberOfBytesRead, nonManagedOverlapped); // Report receieved correctly, copy the unmanaged input buffer over to the managed buffer Marshal.Copy(nonManagedBuffer, inputReportBuffer, 0, numberOfBytesRead); } catch (Exception) { return(false); } // Release non-managed objects before returning Marshal.FreeHGlobal(nonManagedBuffer); Marshal.FreeHGlobal(nonManagedOverlapped); // Close the file handle to release the object Kernel32.CloseHandle(eventObject); return(success); }
public static bool ReadMultipleReportsFromDevice(ref byte[] inputReportBuffer, int numberOfReports, ref DeviceInformationStructure deviceInformation) { var success = false; var numberOfBytesRead = 0; long pointerToBuffer = 0; // Define a temporary buffer for assembling partial data reads into the completed inputReportBuffer var temporaryBuffer = new Byte[inputReportBuffer.Length]; // Range check the number of reports if (numberOfReports == 0) { return(false); } if (numberOfReports > 128) { return(false); } // The size of our inputReportBuffer must be at least the same size as the input report multiplied by the number of reports requested. if (inputReportBuffer.Length != (deviceInformation.Capabilities.InputReportByteLength * numberOfReports)) { // inputReportBuffer is not the right length! return(false); } // The readRawReportFromDevice method will fill the passed read buffer or return false while (pointerToBuffer != (deviceInformation.Capabilities.InputReportByteLength * numberOfReports)) { success = ReadRawReportFromDevice(ref temporaryBuffer, ref numberOfBytesRead, ref deviceInformation); // Was the read successful? if (!success) { return(false); } // Copy the received data into the referenced input buffer Array.Copy(temporaryBuffer, 0, inputReportBuffer, pointerToBuffer, numberOfBytesRead); pointerToBuffer += numberOfBytesRead; } return(success); }
public static bool FindTargetDevice(ref DeviceInformationStructure deviceInformation, bool callOther = true) { TmoShare.WriteLog("DeviceDiscovery:findTargetDevice() -> 开始扫描设备"); var listOfDevicePathNames = new String[128]; // 128 is the maximum number of USB devices allowed on a single host var numberOfDevicesFound = 0; try { // Reset the device detection flag var isDeviceDetected = false; deviceInformation.IsDeviceAttached = false; // Get all the devices with the correct HID GUID bool deviceFoundByGuid = FindHidDevices(ref listOfDevicePathNames, ref numberOfDevicesFound); if (deviceFoundByGuid) { TmoShare.WriteLog("DeviceDiscovery:findTargetDevice() -> 找到一堆设备"); var listIndex = 0; do { TmoShare.WriteLog(string.Format("DeviceDiscovery:findTargetDevice() ->遍历第{0}个设备", listIndex + 1)); deviceInformation.HidHandle = Kernel32.CreateFile(listOfDevicePathNames[listIndex], 0, Constants.FileShareRead | Constants.FileShareWrite, IntPtr.Zero, Constants.OpenExisting, 0, 0); if (!deviceInformation.HidHandle.IsInvalid()) { deviceInformation.Attributes.Size = Marshal.SizeOf(deviceInformation.Attributes); var success = Hid.HidD_GetAttributes(deviceInformation.HidHandle, ref deviceInformation.Attributes); if (success) { TmoShare.WriteLog(string.Format("DeviceDiscovery:findTargetDevice() -> 发现设备 VID_{0}, PID_{1} Ver_{2}", Convert.ToString(deviceInformation.Attributes.VendorID, 16), Convert.ToString(deviceInformation.Attributes.ProductID, 16), Convert.ToString(deviceInformation.Attributes.VersionNumber, 16))); // Do the VID and PID of the device match our target device? if ((deviceInformation.Attributes.VendorID == deviceInformation.TargetVendorId) && (deviceInformation.Attributes.ProductID == deviceInformation.TargetProductId)) { // Matching device found if (string.IsNullOrWhiteSpace(deviceInformation.DevicePathName)) { deviceInformation.DevicePathName = listOfDevicePathNames[listIndex]; isDeviceDetected = true; TmoShare.WriteLog("DeviceDiscovery:findTargetDevice() -> 找到目标设备!"); } else if (string.Compare(deviceInformation.DevicePathName, listOfDevicePathNames[listIndex], true) == 0) { isDeviceDetected = true; TmoShare.WriteLog("DeviceDiscovery:findTargetDevice() -> 找到目标设备!"); } else { TmoShare.WriteLog("DeviceDiscovery:findTargetDevice() -> 不是目标设备... 继续寻找..."); deviceInformation.HidHandle.Close(); } // Store the device's pathname in the device information } else { // Wrong device, close the handle TmoShare.WriteLog("DeviceDiscovery:findTargetDevice() -> 不是目标设备... 继续寻找..."); deviceInformation.HidHandle.Close(); } } else { // Something went rapidly south... give up! TmoShare.WriteLog("DeviceDiscovery:findTargetDevice() -> 识别设备失败, 继续下一个!"); deviceInformation.HidHandle.Close(); } } else { TmoShare.WriteLog("DeviceDiscovery:findTargetDevice() -> 句柄创建失败"); } // Move to the next device, or quit if there are no more devices to examine listIndex++; }while (!((isDeviceDetected || (listIndex == numberOfDevicesFound)))); } // If we found a matching device then we need discover more details about the attached device // and then open read and write handles to the device to allow communication if (isDeviceDetected) { // Query the HID device's capabilities (primarily we are only really interested in the // input and output report byte lengths as this allows us to validate information sent // to and from the device does not exceed the devices capabilities. // // We could determine the 'type' of HID device here too, but since this class is only // for generic HID communication we don't care... if (!callOther) { // Open the readHandle to the device TmoShare.WriteLog("DeviceDiscovery:findTargetDevice() -> 开始创建读文件句柄"); deviceInformation.ReadHandle = Kernel32.CreateFile( deviceInformation.DevicePathName, Constants.GenericRead, Constants.FileShareRead | Constants.FileShareWrite, IntPtr.Zero, Constants.OpenExisting, Constants.FileFlagOverlapped, 0); // Did we open the readHandle successfully? if (deviceInformation.ReadHandle.IsInvalid()) { TmoShare.WriteLog("DeviceDiscovery:findTargetDevice() -> 读文件句柄创建失败" + Marshal.GetLastWin32Error()); return(false); } //Open the writeHandel to the device TmoShare.WriteLog("DeviceDiscovery:findTargetDevice() -> 开始创建写文件句柄"); deviceInformation.WriteHandle = Kernel32.CreateFile( deviceInformation.DevicePathName, Constants.GenericWrite, Constants.FileShareWrite | Constants.FileShareRead, IntPtr.Zero, Constants.OpenExisting, 0, 0); // Did we open the writeHandle successfully? if (deviceInformation.WriteHandle.IsInvalid()) { TmoShare.WriteLog("DeviceDiscovery:findTargetDevice() -> 写文件句柄创建失败" + Marshal.GetLastWin32Error()); return(false); } } QueryDeviceCapabilities(ref deviceInformation); // Device is now discovered and ready for use, update the status deviceInformation.IsDeviceAttached = true; return(true); } // The device wasn't detected. TmoShare.WriteLog("DeviceDiscovery:findTargetDevice() -> 未找到目标设备!"); return(false); } catch (Exception ex) { TmoShare.WriteLog("DeviceDiscovery:findTargetDevice() -> 发生异常:" + ex.Message); return(false); } }
public static void QueryDeviceCapabilities(ref DeviceInformationStructure deviceInformation) { var preparsedData = new IntPtr(); try { // Get the preparsed data from the HID driver Hid.HidD_GetPreparsedData(deviceInformation.HidHandle, ref preparsedData); // Get the HID device's capabilities var result = Hid.HidP_GetCaps(preparsedData, ref deviceInformation.Capabilities); if ((result == 0)) { return; } Debug.WriteLine("usbGenericHidCommunication:queryDeviceCapabilities() -> Device query results:"); Debug.WriteLine("usbGenericHidCommunication:queryDeviceCapabilities() -> Usage: {0}", Convert.ToString(deviceInformation.Capabilities.Usage, 16)); Debug.WriteLine("usbGenericHidCommunication:queryDeviceCapabilities() -> Usage Page: {0}", Convert.ToString(deviceInformation.Capabilities.UsagePage, 16)); Debug.WriteLine("usbGenericHidCommunication:queryDeviceCapabilities() -> Input Report Byte Length: {0}", deviceInformation.Capabilities.InputReportByteLength.ToString(CultureInfo.InvariantCulture)); Debug.WriteLine("usbGenericHidCommunication:queryDeviceCapabilities() -> Output Report Byte Length: {0}", deviceInformation.Capabilities.OutputReportByteLength.ToString(CultureInfo.InvariantCulture)); Debug.WriteLine("usbGenericHidCommunication:queryDeviceCapabilities() -> Feature Report Byte Length: {0}", deviceInformation.Capabilities.FeatureReportByteLength.ToString(CultureInfo.InvariantCulture)); Debug.WriteLine("usbGenericHidCommunication:queryDeviceCapabilities() -> Number of Link Collection Nodes: {0}", deviceInformation.Capabilities.NumberLinkCollectionNodes.ToString(CultureInfo.InvariantCulture)); Debug.WriteLine("usbGenericHidCommunication:queryDeviceCapabilities() -> Number of Input Button Caps: {0}", deviceInformation.Capabilities.NumberInputButtonCaps.ToString(CultureInfo.InvariantCulture)); Debug.WriteLine("usbGenericHidCommunication:queryDeviceCapabilities() -> Number of Input Value Caps: {0}", deviceInformation.Capabilities.NumberInputValueCaps.ToString(CultureInfo.InvariantCulture)); Debug.WriteLine("usbGenericHidCommunication:queryDeviceCapabilities() -> Number of Input Data Indices: {0}", deviceInformation.Capabilities.NumberInputDataIndices.ToString(CultureInfo.InvariantCulture)); Debug.WriteLine("usbGenericHidCommunication:queryDeviceCapabilities() -> Number of Output Button Caps: {0}", deviceInformation.Capabilities.NumberOutputButtonCaps.ToString(CultureInfo.InvariantCulture)); Debug.WriteLine("usbGenericHidCommunication:queryDeviceCapabilities() -> Number of Output Value Caps: {0}", deviceInformation.Capabilities.NumberOutputValueCaps.ToString(CultureInfo.InvariantCulture)); Debug.WriteLine("usbGenericHidCommunication:queryDeviceCapabilities() -> Number of Output Data Indices: {0}", deviceInformation.Capabilities.NumberOutputDataIndices.ToString(CultureInfo.InvariantCulture)); Debug.WriteLine("usbGenericHidCommunication:queryDeviceCapabilities() -> Number of Feature Button Caps: {0}", deviceInformation.Capabilities.NumberFeatureButtonCaps.ToString(CultureInfo.InvariantCulture)); Debug.WriteLine("usbGenericHidCommunication:queryDeviceCapabilities() -> Number of Feature Value Caps: {0}", deviceInformation.Capabilities.NumberFeatureValueCaps.ToString(CultureInfo.InvariantCulture)); Debug.WriteLine("usbGenericHidCommunication:queryDeviceCapabilities() -> Number of Feature Data Indices: {0}", deviceInformation.Capabilities.NumberFeatureDataIndices.ToString(CultureInfo.InvariantCulture)); } catch (Exception) { // Something went badly wrong... this shouldn't happen, so we throw an exception Debug.WriteLine("usbGenericHidCommunication:queryDeviceCapabilities() -> EXECEPTION: An unrecoverable error has occurred!"); throw; } finally { // Free up the memory before finishing if (preparsedData != IntPtr.Zero) { Hid.HidD_FreePreparsedData(preparsedData); } } }
public static bool ReadMultipleReportsFromDevice(ref byte[] inputReportBuffer, int numberOfReports, ref DeviceInformationStructure deviceInformation) { var success = false; var numberOfBytesRead = 0; long pointerToBuffer = 0; // Define a temporary buffer for assembling partial data reads into the completed inputReportBuffer var temporaryBuffer = new Byte[inputReportBuffer.Length]; // Range check the number of reports if (numberOfReports == 0) { Debug.WriteLine( "usbGenericHidCommunication:readMultipleReportsFromDevice(): -> ERROR: You cannot request 0 reports!"); return(false); } if (numberOfReports > 128) { Debug.WriteLine( "usbGenericHidCommunication:readMultipleReportsFromDevice(): -> ERROR: Reference application testing does not verify the code for more than 128 reports"); return(false); } // The size of our inputReportBuffer must be at least the same size as the input report multiplied by the number of reports requested. if (inputReportBuffer.Length != (deviceInformation.Capabilities.InputReportByteLength * numberOfReports)) { // inputReportBuffer is not the right length! Debug.WriteLine( "usbGenericHidCommunication:readMultipleReportsFromDevice(): -> ERROR: The referenced inputReportBuffer size is incorrect for the number of input reports requested!"); return(false); } // The readRawReportFromDevice method will fill the passed read buffer or return false while (pointerToBuffer != (deviceInformation.Capabilities.InputReportByteLength * numberOfReports)) { Debug.WriteLine( "usbGenericHidCommunication:readMultipleReportsFromDevice(): -> Reading from device..."); success = ReadRawReportFromDevice(ref temporaryBuffer, ref numberOfBytesRead, ref deviceInformation); // Was the read successful? if (!success) { return(false); } // Copy the received data into the referenced input buffer Array.Copy(temporaryBuffer, 0, inputReportBuffer, pointerToBuffer, numberOfBytesRead); pointerToBuffer += numberOfBytesRead; } return(success); }
public static bool FindTargetDevice(ref DeviceInformationStructure deviceInformation) { Debug.WriteLine("usbGenericHidCommunication:findTargetDevice() -> Method called"); var listOfDevicePathNames = new String[128]; // 128 is the maximum number of USB devices allowed on a single host var numberOfDevicesFound = 0; try { // Reset the device detection flag var isDeviceDetected = false; deviceInformation.IsDeviceAttached = false; // Get all the devices with the correct HID GUID var deviceFoundByGuid = FindHidDevices(ref listOfDevicePathNames, ref numberOfDevicesFound); if (deviceFoundByGuid) { Debug.WriteLine("usbGenericHidCommunication:findTargetDevice() -> Devices with matching GUID found..."); var listIndex = 0; do { Debug.WriteLine("usbGenericHidCommunication:findTargetDevice() -> Performing CreateFile to listIndex {0}", listIndex); deviceInformation.HidHandle = Kernel32.CreateFile(listOfDevicePathNames[listIndex], 0, Constants.FileShareRead | Constants.FileShareWrite, IntPtr.Zero, Constants.OpenExisting, 0, 0); if (!deviceInformation.HidHandle.IsInvalid) { deviceInformation.Attributes.Size = Marshal.SizeOf(deviceInformation.Attributes); var success = Hid.HidD_GetAttributes(deviceInformation.HidHandle, ref deviceInformation.Attributes); if (success) { Debug.WriteLine("usbGenericHidCommunication:findTargetDevice() -> Found device with VID {0}, PID {1} and Version number {2}", Convert.ToString(deviceInformation.Attributes.VendorID, 16), Convert.ToString(deviceInformation.Attributes.ProductID, 16), Convert.ToString(deviceInformation.Attributes.VersionNumber, 16)); // Do the VID and PID of the device match our target device? if ((deviceInformation.Attributes.VendorID == deviceInformation.TargetVendorId) && (deviceInformation.Attributes.ProductID == deviceInformation.TargetProductId)) { // Matching device found Debug.WriteLine("usbGenericHidCommunication:findTargetDevice() -> Device with matching VID and PID found!"); isDeviceDetected = true; // Store the device's pathname in the device information deviceInformation.DevicePathName = listOfDevicePathNames[listIndex]; } else { // Wrong device, close the handle Debug.WriteLine("usbGenericHidCommunication:findTargetDevice() -> Device didn't match... Continuing..."); deviceInformation.HidHandle.Close(); } } else { // Something went rapidly south... give up! Debug.WriteLine("usbGenericHidCommunication:findTargetDevice() -> Something bad happened - couldn't fill the HIDD_ATTRIBUTES, giving up!"); deviceInformation.HidHandle.Close(); } } // Move to the next device, or quit if there are no more devices to examine listIndex++; }while (!((isDeviceDetected || (listIndex == numberOfDevicesFound + 1)))); } // If we found a matching device then we need discover more details about the attached device // and then open read and write handles to the device to allow communication if (isDeviceDetected) { // Query the HID device's capabilities (primarily we are only really interested in the // input and output report byte lengths as this allows us to validate information sent // to and from the device does not exceed the devices capabilities. // // We could determine the 'type' of HID device here too, but since this class is only // for generic HID communication we don't care... QueryDeviceCapabilities(ref deviceInformation); // Open the readHandle to the device Debug.WriteLine("usbGenericHidCommunication:findTargetDevice() -> Opening a readHandle to the device"); deviceInformation.ReadHandle = Kernel32.CreateFile( deviceInformation.DevicePathName, Constants.GenericRead, Constants.FileShareRead | Constants.FileShareWrite, IntPtr.Zero, Constants.OpenExisting, Constants.FileFlagOverlapped, 0); // Did we open the readHandle successfully? if (deviceInformation.ReadHandle.IsInvalid) { Debug.WriteLine("usbGenericHidCommunication:findTargetDevice() -> Unable to open a readHandle to the device!"); return(false); } Debug.WriteLine("usbGenericHidCommunication:findTargetDevice() -> Opening a writeHandle to the device"); deviceInformation.WriteHandle = Kernel32.CreateFile( deviceInformation.DevicePathName, Constants.GenericWrite, Constants.FileShareRead | Constants.FileShareWrite, IntPtr.Zero, Constants.OpenExisting, 0, 0); // Did we open the writeHandle successfully? if (deviceInformation.WriteHandle.IsInvalid) { Debug.WriteLine("usbGenericHidCommunication:findTargetDevice() -> Unable to open a writeHandle to the device!"); // Attempt to close the writeHandle deviceInformation.WriteHandle.Close(); return(false); } // Device is now discovered and ready for use, update the status deviceInformation.IsDeviceAttached = true; return(true); } // The device wasn't detected. Debug.WriteLine("usbGenericHidCommunication:findTargetDevice() -> No matching device found!"); return(false); } catch (Exception) { Debug.WriteLine("usbGenericHidCommunication:findTargetDevice() -> EXCEPTION: Unknown - device not found"); return(false); } }