/// <summary> /// Opens device in persistent mode (reopens after device removal-reconnection) /// </summary> /// <param name="in_path"></param> /// <returns></returns> public bool Open(string in_path) { bool success = true; // store devcie path m_device_path = in_path; // open device m_device_handle = USBNativeMethods.CreateFile(in_path, USBNativeMethods.GENERIC_READ | USBNativeMethods.GENERIC_WRITE, USBNativeMethods.FILE_SHARE_READ | USBNativeMethods.FILE_SHARE_WRITE, IntPtr.Zero, USBNativeMethods.OPEN_EXISTING, USBNativeMethods.FILE_FLAG_OVERLAPPED, 0); if (m_device_handle.IsInvalid) { success = false; } // get report length if (success) { IntPtr preparsed_data_pointer = new IntPtr(); if (USBNativeMethods.HidD_GetPreparsedData(m_device_handle, ref preparsed_data_pointer)) { USBNativeMethods.HIDP_CAPS capabilities = new USBNativeMethods.HIDP_CAPS(); // Get report lengths USBNativeMethods.HidP_GetCaps(preparsed_data_pointer, ref capabilities); // Store report length m_input_report_length = capabilities.InputReportByteLength; m_output_report_length = capabilities.OutputReportByteLength; m_feature_report_length = capabilities.FeatureReportByteLength; // No need for PreparsedData any more, so free the memory it's using. USBNativeMethods.HidD_FreePreparsedData(ref preparsed_data_pointer); // check report size if (m_input_report_length != USBNativeMethods.HID_MAX_REPORT_SIZE || m_output_report_length != USBNativeMethods.HID_MAX_REPORT_SIZE) { success = false; } } else { success = false; } } if (success) { // determine buffer size (use the biggest report size, normally they must be same) int buffer_size = m_input_report_length; if (m_output_report_length > buffer_size) { buffer_size = m_output_report_length; } if (m_feature_report_length > buffer_size) { buffer_size = m_feature_report_length; } // get file stream m_file_stream = new FileStream(m_device_handle, FileAccess.ReadWrite, buffer_size, true); } return(success); }
/// <summary> /// Gets the list of the dvices /// </summary> /// <param name="in_vid">Vendor ID</param> /// <param name="in_pid">Product ID</param> /// <returns></returns> public List <DeviceInfo> EnumerateDevices() { bool result; int device_index = 0; List <DeviceInfo> device_info_collection = new List <DeviceInfo>(); // init Guid hid_guid = Guid.Empty; //Obtain the device interface GUID for the HID class USBNativeMethods.HidD_GetHidGuid(ref hid_guid); // Requesting a pointer to a device information set IntPtr device_info_set = USBNativeMethods.SetupDiGetClassDevs(ref hid_guid, IntPtr.Zero, IntPtr.Zero, USBNativeMethods.DIGCF_PRESENT | USBNativeMethods.DIGCF_INTERFACEDEVICE); // The cbSize element of the MyDeviceInterfaceData structure must be set to // the structure's size in bytes. USBNativeMethods.SP_DEVICE_INTERFACE_DATA device_interface_data = new USBNativeMethods.SP_DEVICE_INTERFACE_DATA(); device_interface_data.Size = Marshal.SizeOf(device_interface_data); device_index = 0; while (true) { // Begin with 0 and increment through the device information set until // no more devices are available. result = USBNativeMethods.SetupDiEnumDeviceInterfaces(device_info_set, IntPtr.Zero, ref hid_guid, device_index, ref device_interface_data); if (!result) { // If it fails, that means we've reached the end of the list. break; } // A device is present. // Find out how big of a buffer is needed. Int32 buffer_size = 0; result = USBNativeMethods.SetupDiGetDeviceInterfaceDetail(device_info_set, ref device_interface_data, IntPtr.Zero, 0, ref buffer_size, IntPtr.Zero); if (result) { // This success is unexpected! We wanted to get an error, with the attendant // information of how big to make the buffer for a successful call. break; } // Allocate memory for the SP_DEVICE_INTERFACE_DETAIL_DATA structure, using the returned Length. IntPtr detail_data_buffer = Marshal.AllocHGlobal(buffer_size); // Store cbSize in the first bytes of the array. The number of bytes varies with 32-bit and 64-bit systems. Marshal.WriteInt32(detail_data_buffer, (IntPtr.Size == 4) ? (IntPtr.Size + Marshal.SystemDefaultCharSize) : 8); // Call SetupDiGetDeviceInterfaceDetail again. // This time, pass a pointer to DetailDataBuffer // and the returned required buffer size. result = USBNativeMethods.SetupDiGetDeviceInterfaceDetail(device_info_set, ref device_interface_data, detail_data_buffer, buffer_size, ref buffer_size, IntPtr.Zero); if (result) { // Skip over cbsize (4 bytes) to get the address of the devicePathName. IntPtr device_pathname_pointer = new IntPtr(detail_data_buffer.ToInt64() + sizeof(Int32)); // Get the String containing the devicePathName. string device_pathname = Marshal.PtrToStringAuto(device_pathname_pointer); // Open a handle to the device. SafeFileHandle device_handle; device_handle = USBNativeMethods.CreateFile(device_pathname, USBNativeMethods.GENERIC_READ | USBNativeMethods.GENERIC_WRITE, USBNativeMethods.FILE_SHARE_READ | USBNativeMethods.FILE_SHARE_WRITE, IntPtr.Zero, USBNativeMethods.OPEN_EXISTING, 0, 0); if (!device_handle.IsInvalid) { USBNativeMethods.HIDD_ATTRIBUTES attributes = new USBNativeMethods.HIDD_ATTRIBUTES(); // Set the Size to the number of bytes in the structure. attributes.Size = Marshal.SizeOf(attributes); // Requests information from the device. result = USBNativeMethods.HidD_GetAttributes(device_handle, ref attributes); // check vendor and product id if (attributes.VendorID == VID && attributes.ProductID == PID) { StringBuilder serial_number = new StringBuilder(1024); if (USBNativeMethods.HidD_GetSerialNumberString(device_handle, serial_number, serial_number.Capacity)) { DeviceInfo device_info = new DeviceInfo(); device_info.DevicePath = device_pathname; device_info.SerialNumber = serial_number.ToString(); device_info_collection.Add(device_info); } } // close handle device_handle.Close(); } } // Free the memory used by the detailData structure (no longer needed). Marshal.FreeHGlobal(detail_data_buffer); // next device device_index++; } // free device info set if (device_info_set != IntPtr.Zero) { USBNativeMethods.SetupDiDestroyDeviceInfoList(device_info_set); } return(device_info_collection); }