diff --git a/include/CaptureDeviceSpecific/usb_generic.hpp b/include/CaptureDeviceSpecific/usb_generic.hpp index 6cb593c..0245546 100644 --- a/include/CaptureDeviceSpecific/usb_generic.hpp +++ b/include/CaptureDeviceSpecific/usb_generic.hpp @@ -10,5 +10,7 @@ void usb_init(); void usb_close(); bool usb_is_initialized(); int get_usb_total_filtered_devices(const uint16_t valid_vids[], size_t num_vids, const uint16_t valid_pids[], size_t num_pids); +void libusb_check_and_detach_kernel_driver(void* handle, int interface); +int libusb_check_and_set_configuration(void* handle, int wanted_configuration); #endif diff --git a/source/CaptureDeviceSpecific/3DSCapture_FTD3/3dscapture_ftd3_libusb_comms.cpp b/source/CaptureDeviceSpecific/3DSCapture_FTD3/3dscapture_ftd3_libusb_comms.cpp index cedfb6d..f34fee4 100644 --- a/source/CaptureDeviceSpecific/3DSCapture_FTD3/3dscapture_ftd3_libusb_comms.cpp +++ b/source/CaptureDeviceSpecific/3DSCapture_FTD3/3dscapture_ftd3_libusb_comms.cpp @@ -23,6 +23,8 @@ #define FTD3_COMMAND_TIMEOUT 500 +#define DEFAULT_CONFIGURATION 1 + #define FTD3_COMMAND_INTERFACE 0 #define FTD3_BULK_INTERFACE 1 @@ -177,7 +179,14 @@ int ftd3_libusb_set_stream_pipe(ftd3_device_device_handlers* handlers, int pipe, static bool ftd3_libusb_setup_connection(libusb_device_handle* handle, bool* claimed_cmd, bool* claimed_bulk) { *claimed_cmd = false; *claimed_bulk = false; - int result = libusb_claim_interface(handle, FTD3_COMMAND_INTERFACE); + libusb_check_and_detach_kernel_driver(handle, FTD3_COMMAND_INTERFACE); + libusb_check_and_detach_kernel_driver(handle, FTD3_BULK_INTERFACE); + int result = libusb_check_and_set_configuration(handle, DEFAULT_CONFIGURATION); + if(result != LIBUSB_SUCCESS) + return false; + libusb_check_and_detach_kernel_driver(handle, FTD3_COMMAND_INTERFACE); + libusb_check_and_detach_kernel_driver(handle, FTD3_BULK_INTERFACE); + result = libusb_claim_interface(handle, FTD3_COMMAND_INTERFACE); if(result != LIBUSB_SUCCESS) return false; *claimed_cmd = true; diff --git a/source/CaptureDeviceSpecific/DSCapture_FTD2/dscapture_ftd2_libusb.cpp b/source/CaptureDeviceSpecific/DSCapture_FTD2/dscapture_ftd2_libusb.cpp index e9d71fc..55770df 100644 --- a/source/CaptureDeviceSpecific/DSCapture_FTD2/dscapture_ftd2_libusb.cpp +++ b/source/CaptureDeviceSpecific/DSCapture_FTD2/dscapture_ftd2_libusb.cpp @@ -125,6 +125,11 @@ static int init_handle_and_populate_device_info_ftd2_libusb(libusb_device_handle int retval = libusb_get_device_descriptor(dev, &desc); if(retval < 0) return retval; + *curr_descriptor = NULL; + *curr_descriptor = get_device_descriptor(desc.idVendor, desc.idProduct); + if((desc.bcdUSB < 0x0200) || ((*curr_descriptor) == NULL)) + return LIBUSB_ERROR_OTHER; + retval = libusb_open(dev, dev_handle); if(retval || ((*dev_handle) == NULL)) return retval; @@ -133,27 +138,16 @@ static int init_handle_and_populate_device_info_ftd2_libusb(libusb_device_handle close_handle_ftd2_libusb(*dev_handle, false); return retval; } - retval = libusb_kernel_driver_active(*dev_handle, DEFAULT_INTERFACE); - if(retval == 1) - libusb_detach_kernel_driver(*dev_handle, DEFAULT_INTERFACE); - retval = libusb_set_configuration(*dev_handle, DEFAULT_CONFIGURATION); + libusb_check_and_detach_kernel_driver(*dev_handle, DEFAULT_INTERFACE); + retval = libusb_check_and_set_configuration(*dev_handle, DEFAULT_CONFIGURATION); if(retval != LIBUSB_SUCCESS) - return false; - retval = libusb_kernel_driver_active(*dev_handle, DEFAULT_INTERFACE); - if(retval == 1) - libusb_detach_kernel_driver(*dev_handle, DEFAULT_INTERFACE); + return retval; + libusb_check_and_detach_kernel_driver(*dev_handle, DEFAULT_INTERFACE); retval = libusb_claim_interface(*dev_handle, DEFAULT_INTERFACE); if(retval != LIBUSB_SUCCESS) { close_handle_ftd2_libusb(*dev_handle, false); return retval; } - *curr_descriptor = NULL; - if(retval >= 0) - *curr_descriptor = get_device_descriptor(desc.idVendor, desc.idProduct); - if((desc.bcdUSB < 0x0200) || ((*curr_descriptor) == NULL)) { - close_handle_ftd2_libusb(*dev_handle, true); - return LIBUSB_ERROR_OTHER; - } return LIBUSB_SUCCESS; } diff --git a/source/CaptureDeviceSpecific/ISDevices/usb_is_device_libusb.cpp b/source/CaptureDeviceSpecific/ISDevices/usb_is_device_libusb.cpp index bf31edb..6d2973a 100644 --- a/source/CaptureDeviceSpecific/ISDevices/usb_is_device_libusb.cpp +++ b/source/CaptureDeviceSpecific/ISDevices/usb_is_device_libusb.cpp @@ -50,8 +50,11 @@ void is_device_libusb_close_thread(std::thread* thread_ptr, bool* usb_thread_run } static bool is_device_libusb_setup_connection(libusb_device_handle* handle, const is_device_usb_device* usb_device_desc) { - if (libusb_set_configuration(handle, usb_device_desc->default_config) != LIBUSB_SUCCESS) + libusb_check_and_detach_kernel_driver(handle, usb_device_desc->default_interface); + int result = libusb_check_and_set_configuration(handle, usb_device_desc->default_config); + if(result != LIBUSB_SUCCESS) return false; + libusb_check_and_detach_kernel_driver(handle, usb_device_desc->default_interface); if(libusb_claim_interface(handle, usb_device_desc->default_interface) != LIBUSB_SUCCESS) return false; if(usb_device_desc->do_pipe_clear_reset) { diff --git a/source/CaptureDeviceSpecific/Nisetro/cypress_nisetro_libusb_comms.cpp b/source/CaptureDeviceSpecific/Nisetro/cypress_nisetro_libusb_comms.cpp index 2307062..f23eb65 100644 --- a/source/CaptureDeviceSpecific/Nisetro/cypress_nisetro_libusb_comms.cpp +++ b/source/CaptureDeviceSpecific/Nisetro/cypress_nisetro_libusb_comms.cpp @@ -105,15 +105,11 @@ int cypress_libusb_async_in_start(cyni_device_device_handlers* handlers, const c static bool cypress_libusb_setup_connection(libusb_device_handle* handle, const cyni_device_usb_device* usb_device_desc, bool *claimed) { *claimed = false; - int result = libusb_kernel_driver_active(handle, usb_device_desc->default_interface); - if(result == 1) - libusb_detach_kernel_driver(handle, usb_device_desc->default_interface); - result = libusb_set_configuration(handle, usb_device_desc->default_config); + libusb_check_and_detach_kernel_driver(handle, usb_device_desc->default_interface); + int result = libusb_check_and_set_configuration(handle, usb_device_desc->default_config); if(result != LIBUSB_SUCCESS) return false; - result = libusb_kernel_driver_active(handle, usb_device_desc->default_interface); - if(result == 1) - libusb_detach_kernel_driver(handle, usb_device_desc->default_interface); + libusb_check_and_detach_kernel_driver(handle, usb_device_desc->default_interface); result = libusb_claim_interface(handle, usb_device_desc->default_interface); if(result != LIBUSB_SUCCESS) return false; diff --git a/source/CaptureDeviceSpecific/usb_ds_3ds_capture.cpp b/source/CaptureDeviceSpecific/usb_ds_3ds_capture.cpp index e846d9e..97f78fb 100644 --- a/source/CaptureDeviceSpecific/usb_ds_3ds_capture.cpp +++ b/source/CaptureDeviceSpecific/usb_ds_3ds_capture.cpp @@ -132,6 +132,15 @@ static std::string get_serial(libusb_device_handle *handle, libusb_device_descri return serial_str; } +static int do_usb_config_device(libusb_device_handle *handle, const usb_device* usb_device_desc) { + libusb_check_and_detach_kernel_driver(handle, usb_device_desc->capture_interface); + int result = libusb_check_and_set_configuration(handle, usb_device_desc->default_config); + if(result != LIBUSB_SUCCESS) + return result; + libusb_check_and_detach_kernel_driver(handle, usb_device_desc->capture_interface); + return result; +} + static int insert_device(std::vector &devices_list, const usb_device* usb_device_desc, libusb_device *usb_device, libusb_device_descriptor *usb_descriptor, int &curr_serial_extra_id) { libusb_device_handle *handle = NULL; uint8_t data[SERIAL_NUMBER_SIZE]; @@ -140,6 +149,11 @@ static int insert_device(std::vector &devices_list, const usb_dev int result = libusb_open(usb_device, &handle); if(result || (handle == NULL)) return result; + result = do_usb_config_device(handle, usb_device_desc); + if(result != LIBUSB_SUCCESS) { + libusb_close(handle); + return result; + } result = libusb_claim_interface(handle, usb_device_desc->capture_interface); if(result == LIBUSB_SUCCESS) libusb_release_interface(handle, usb_device_desc->capture_interface); @@ -354,7 +368,7 @@ bool connect_usb(bool print_failed, CaptureData* capture_data, CaptureDevice* de capture_error_print(true, capture_data, "Device not found"); return false; } - if(libusb_set_configuration(dev, usb_device_desc->default_config) != LIBUSB_SUCCESS) { + if(do_usb_config_device(dev, usb_device_desc) != LIBUSB_SUCCESS) { capture_error_print(true, capture_data, "Configuration failed"); capture_end(dev, usb_device_desc, false); return false; diff --git a/source/CaptureDeviceSpecific/usb_generic.cpp b/source/CaptureDeviceSpecific/usb_generic.cpp index 2c088b8..70c01d5 100644 --- a/source/CaptureDeviceSpecific/usb_generic.cpp +++ b/source/CaptureDeviceSpecific/usb_generic.cpp @@ -65,3 +65,25 @@ int get_usb_total_filtered_devices(const uint16_t valid_vids[], size_t num_vids, return num_devices_found; } + +void libusb_check_and_detach_kernel_driver(void* handle, int interface) { + if(handle == NULL) + return; + libusb_device_handle* in_handle = (libusb_device_handle*)handle; + int retval = libusb_kernel_driver_active(in_handle, interface); + if(retval == 1) + libusb_detach_kernel_driver(in_handle, interface); +} + +int libusb_check_and_set_configuration(void* handle, int wanted_configuration) { + if(handle == NULL) + return LIBUSB_ERROR_OTHER; + libusb_device_handle* in_handle = (libusb_device_handle*)handle; + int curr_configuration = 0; + int result = libusb_get_configuration(in_handle, &curr_configuration); + if(result != LIBUSB_SUCCESS) + return result; + if(curr_configuration != wanted_configuration) + result = libusb_set_configuration(in_handle, wanted_configuration); + return result; +}