summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/libirecovery.c201
1 files changed, 124 insertions, 77 deletions
diff --git a/src/libirecovery.c b/src/libirecovery.c
index 40fd88f..a85cd97 100644
--- a/src/libirecovery.c
+++ b/src/libirecovery.c
@@ -1787,27 +1787,94 @@ static irecv_error_t iokit_open_with_ecid(irecv_client_t* pclient, uint64_t ecid
1787#endif 1787#endif
1788#endif 1788#endif
1789 1789
1790irecv_error_t irecv_open_with_ecid(irecv_client_t* pclient, uint64_t ecid) 1790#ifndef WIN32
1791{ 1791#ifndef HAVE_IOKIT
1792#ifdef USE_DUMMY 1792static irecv_error_t libusb_usb_open_handle_with_descriptor_and_ecid(irecv_client_t *pclient, struct libusb_device_handle *usb_handle, struct libusb_device_descriptor *usb_descriptor, uint64_t ecid){
1793 return IRECV_E_UNSUPPORTED; 1793 irecv_error_t ret = IRECV_E_UNABLE_TO_CONNECT;
1794#else 1794 irecv_error_t error = IRECV_E_UNABLE_TO_CONNECT;
1795 int ret = IRECV_E_UNABLE_TO_CONNECT;
1796 1795
1797 if (libirecovery_debug) { 1796 irecv_client_t client = (irecv_client_t) malloc(sizeof(struct irecv_client_private));
1798 irecv_set_debug_level(libirecovery_debug); 1797 if (client == NULL) {
1798 libusb_close(usb_handle);
1799 return IRECV_E_OUT_OF_MEMORY;
1799 } 1800 }
1800#ifndef WIN32 1801
1801#ifdef HAVE_IOKIT 1802 memset(client, '\0', sizeof(struct irecv_client_private));
1802 ret = iokit_open_with_ecid(pclient, ecid); 1803 client->usb_interface = 0;
1803#else 1804 client->handle = usb_handle;
1805 client->mode = usb_descriptor->idProduct;
1806
1807 if (client->mode != KIS_PRODUCT_ID) {
1808 char serial_str[256];
1809 memset(serial_str, 0, 256);
1810 irecv_get_string_descriptor_ascii(client, usb_descriptor->iSerialNumber, (unsigned char*)serial_str, 255);
1811 irecv_load_device_info_from_iboot_string(client, serial_str);
1812 }
1813
1814 if (ecid != 0 && client->mode != KIS_PRODUCT_ID) {
1815 if (client->device_info.ecid != ecid) {
1816 irecv_close(client);
1817 return IRECV_E_NO_DEVICE; //wrong device
1818 }
1819 debug("found device with ECID %016" PRIx64 "\n", (uint64_t)ecid);
1820 }
1821
1822 error = irecv_usb_set_configuration(client, 1);
1823 if (error != IRECV_E_SUCCESS) {
1824 irecv_close(client);
1825 return error;
1826 }
1827
1828 if ((client->mode != IRECV_K_DFU_MODE) && (client->mode != IRECV_K_WTF_MODE) && (client->mode != KIS_PRODUCT_ID)) {
1829 error = irecv_usb_set_interface(client, 0, 0);
1830 if (client->mode > IRECV_K_RECOVERY_MODE_2) {
1831 error = irecv_usb_set_interface(client, 1, 1);
1832 }
1833 } else {
1834 error = irecv_usb_set_interface(client, 0, 0);
1835 }
1836
1837 if (error != IRECV_E_SUCCESS) {
1838 irecv_close(client);
1839 return error;
1840 }
1841
1842 if (client->mode == KIS_PRODUCT_ID) {
1843 error = irecv_kis_init(client);
1844 if (error != IRECV_E_SUCCESS) {
1845 debug("irecv_kis_init failed, error %d\n", error);
1846 return error;
1847 }
1848
1849 error = irecv_kis_load_device_info(client);
1850 if (error != IRECV_E_SUCCESS) {
1851 debug("irecv_kis_load_device_info failed, error %d\n", error);
1852 return error;
1853 }
1854 if (ecid != 0 && client->device_info.ecid != ecid) {
1855 irecv_close(client);
1856 return IRECV_E_NO_DEVICE; //wrong device
1857 }
1858 debug("found device with ECID %016" PRIx64 "\n", (uint64_t)ecid);
1859 } else {
1860 irecv_copy_nonce_with_tag(client, "NONC", &client->device_info.ap_nonce, &client->device_info.ap_nonce_size);
1861 irecv_copy_nonce_with_tag(client, "SNON", &client->device_info.sep_nonce, &client->device_info.sep_nonce_size);
1862 }
1863
1864 ret = IRECV_E_SUCCESS;
1865 *pclient = client;
1866 return ret;
1867}
1868
1869static irecv_error_t libusb_open_with_ecid(irecv_client_t* pclient, uint64_t ecid)
1870{
1871 irecv_error_t ret = IRECV_E_UNABLE_TO_CONNECT;
1804 int i = 0; 1872 int i = 0;
1805 struct libusb_device* usb_device = NULL; 1873 struct libusb_device* usb_device = NULL;
1806 struct libusb_device** usb_device_list = NULL; 1874 struct libusb_device** usb_device_list = NULL;
1807 struct libusb_device_descriptor usb_descriptor; 1875 struct libusb_device_descriptor usb_descriptor;
1808 1876
1809 *pclient = NULL; 1877 *pclient = NULL;
1810 irecv_error_t error = IRECV_E_SUCCESS;
1811 int usb_device_count = libusb_get_device_list(libirecovery_context, &usb_device_list); 1878 int usb_device_count = libusb_get_device_list(libirecovery_context, &usb_device_list);
1812 for (i = 0; i < usb_device_count; i++) { 1879 for (i = 0; i < usb_device_count; i++) {
1813 usb_device = usb_device_list[i]; 1880 usb_device = usb_device_list[i];
@@ -1819,7 +1886,8 @@ irecv_error_t irecv_open_with_ecid(irecv_client_t* pclient, uint64_t ecid)
1819 usb_descriptor.idProduct == IRECV_K_RECOVERY_MODE_3 || 1886 usb_descriptor.idProduct == IRECV_K_RECOVERY_MODE_3 ||
1820 usb_descriptor.idProduct == IRECV_K_RECOVERY_MODE_4 || 1887 usb_descriptor.idProduct == IRECV_K_RECOVERY_MODE_4 ||
1821 usb_descriptor.idProduct == IRECV_K_WTF_MODE || 1888 usb_descriptor.idProduct == IRECV_K_WTF_MODE ||
1822 usb_descriptor.idProduct == IRECV_K_DFU_MODE) { 1889 usb_descriptor.idProduct == IRECV_K_DFU_MODE ||
1890 usb_descriptor.idProduct == KIS_PRODUCT_ID) {
1823 1891
1824 if (ecid == IRECV_K_WTF_MODE) { 1892 if (ecid == IRECV_K_WTF_MODE) {
1825 if (usb_descriptor.idProduct != IRECV_K_WTF_MODE) { 1893 if (usb_descriptor.idProduct != IRECV_K_WTF_MODE) {
@@ -1850,64 +1918,34 @@ irecv_error_t irecv_open_with_ecid(irecv_client_t* pclient, uint64_t ecid)
1850 return IRECV_E_UNABLE_TO_CONNECT; 1918 return IRECV_E_UNABLE_TO_CONNECT;
1851 } 1919 }
1852 1920
1853 irecv_client_t client = (irecv_client_t) malloc(sizeof(struct irecv_client_private)); 1921 ret = libusb_usb_open_handle_with_descriptor_and_ecid(pclient, usb_handle, &usb_descriptor, ecid);
1854 if (client == NULL) { 1922 if (ret == IRECV_E_SUCCESS) {
1855 libusb_free_device_list(usb_device_list, 1); 1923 break;
1856 libusb_close(usb_handle);
1857 return IRECV_E_OUT_OF_MEMORY;
1858 }
1859
1860 memset(client, '\0', sizeof(struct irecv_client_private));
1861 client->usb_interface = 0;
1862 client->handle = usb_handle;
1863 client->mode = usb_descriptor.idProduct;
1864
1865 char serial_str[256];
1866 memset(serial_str, 0, 256);
1867 irecv_get_string_descriptor_ascii(client, usb_descriptor.iSerialNumber, (unsigned char*)serial_str, 255);
1868
1869 irecv_load_device_info_from_iboot_string(client, serial_str);
1870
1871 irecv_copy_nonce_with_tag(client, "NONC", &client->device_info.ap_nonce, &client->device_info.ap_nonce_size);
1872 irecv_copy_nonce_with_tag(client, "SNON", &client->device_info.sep_nonce, &client->device_info.sep_nonce_size);
1873
1874 if (ecid != 0) {
1875 if (client->device_info.ecid != ecid) {
1876 irecv_close(client);
1877 continue;
1878 }
1879 debug("found device with ECID %016" PRIx64 "\n", (uint64_t)ecid);
1880 }
1881
1882 error = irecv_usb_set_configuration(client, 1);
1883 if (error != IRECV_E_SUCCESS) {
1884 libusb_free_device_list(usb_device_list, 1);
1885 irecv_close(client);
1886 return error;
1887 }
1888
1889 if ((client->mode != IRECV_K_DFU_MODE) && (client->mode != IRECV_K_WTF_MODE)) {
1890 error = irecv_usb_set_interface(client, 0, 0);
1891 if (client->mode > IRECV_K_RECOVERY_MODE_2) {
1892 error = irecv_usb_set_interface(client, 1, 1);
1893 }
1894 } else {
1895 error = irecv_usb_set_interface(client, 0, 0);
1896 }
1897
1898 if (error != IRECV_E_SUCCESS) {
1899 libusb_free_device_list(usb_device_list, 1);
1900 irecv_close(client);
1901 return error;
1902 } 1924 }
1903
1904 *pclient = client;
1905 ret = IRECV_E_SUCCESS;
1906 break;
1907 } 1925 }
1908 } 1926 }
1909 } 1927 }
1910 libusb_free_device_list(usb_device_list, 1); 1928 libusb_free_device_list(usb_device_list, 1);
1929 return ret;
1930}
1931#endif
1932#endif
1933
1934irecv_error_t irecv_open_with_ecid(irecv_client_t* pclient, uint64_t ecid)
1935{
1936#ifdef USE_DUMMY
1937 return IRECV_E_UNSUPPORTED;
1938#else
1939 int ret = IRECV_E_UNABLE_TO_CONNECT;
1940
1941 if (libirecovery_debug) {
1942 irecv_set_debug_level(libirecovery_debug);
1943 }
1944#ifndef WIN32
1945#ifdef HAVE_IOKIT
1946 ret = iokit_open_with_ecid(pclient, ecid);
1947#else
1948 ret = libusb_open_with_ecid(pclient, ecid);
1911#endif 1949#endif
1912#else 1950#else
1913 ret = mobiledevice_connect(pclient, ecid); 1951 ret = mobiledevice_connect(pclient, ecid);
@@ -2438,16 +2476,25 @@ static void* _irecv_handle_device_add(void *userdata)
2438 } 2476 }
2439 2477
2440 if (product_id == KIS_PRODUCT_ID) { 2478 if (product_id == KIS_PRODUCT_ID) {
2441 debug("%s: ERROR: KIS currently not supported with this backend!\n", __func__); 2479 irecv_client_t client;
2442 return NULL; 2480 irecv_error_t error = libusb_usb_open_handle_with_descriptor_and_ecid(&client, usb_handle, &devdesc, 0);
2443 } 2481 if (error != IRECV_E_SUCCESS) {
2482 debug("%s: ERROR: could not open KIS device!\n", __func__);
2483 return NULL;
2484 }
2444 2485
2445 libusb_error = libusb_get_string_descriptor_ascii(usb_handle, devdesc.iSerialNumber, (unsigned char*)serial_str, 255); 2486 strcpy(serial_str, client->device_info.serial_string);
2446 if (libusb_error < 0) { 2487 product_id = client->mode;
2447 debug("%s: Failed to get string descriptor: %s\n", __func__, libusb_error_name(libusb_error)); 2488
2448 return 0; 2489 irecv_close(client);
2490 } else {
2491 libusb_error = libusb_get_string_descriptor_ascii(usb_handle, devdesc.iSerialNumber, (unsigned char*)serial_str, 255);
2492 if (libusb_error < 0) {
2493 debug("%s: Failed to get string descriptor: %s\n", __func__, libusb_error_name(libusb_error));
2494 return 0;
2495 }
2496 libusb_close(usb_handle);
2449 } 2497 }
2450 libusb_close(usb_handle);
2451#endif /* !HAVE_IOKIT */ 2498#endif /* !HAVE_IOKIT */
2452#endif /* !WIN32 */ 2499#endif /* !WIN32 */
2453 memset(&client_loc, '\0', sizeof(client_loc)); 2500 memset(&client_loc, '\0', sizeof(client_loc));
@@ -2745,7 +2792,7 @@ static void *_irecv_event_handler(void* data)
2745#else /* !HAVE_IOKIT */ 2792#else /* !HAVE_IOKIT */
2746#ifdef HAVE_LIBUSB_HOTPLUG_API 2793#ifdef HAVE_LIBUSB_HOTPLUG_API
2747 static libusb_hotplug_callback_handle usb_hotplug_cb_handle; 2794 static libusb_hotplug_callback_handle usb_hotplug_cb_handle;
2748 libusb_hotplug_register_callback(irecv_hotplug_ctx, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED | LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT, LIBUSB_HOTPLUG_ENUMERATE, APPLE_VENDOR_ID, LIBUSB_HOTPLUG_MATCH_ANY, 0, _irecv_usb_hotplug_cb, NULL, &usb_hotplug_cb_handle); 2795 libusb_hotplug_register_callback(irecv_hotplug_ctx, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED | LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT, LIBUSB_HOTPLUG_ENUMERATE, APPLE_VENDOR_ID, LIBUSB_HOTPLUG_MATCH_ANY, LIBUSB_HOTPLUG_MATCH_ANY, _irecv_usb_hotplug_cb, NULL, &usb_hotplug_cb_handle);
2749 int running = 1; 2796 int running = 1;
2750 2797
2751 mutex_lock(&(info->startup_mutex)); 2798 mutex_lock(&(info->startup_mutex));
@@ -2969,7 +3016,7 @@ irecv_error_t irecv_close(irecv_client_t client)
2969 } 3016 }
2970#else 3017#else
2971 if (client->handle != NULL) { 3018 if (client->handle != NULL) {
2972 if ((client->mode != IRECV_K_DFU_MODE) && (client->mode != IRECV_K_WTF_MODE)) { 3019 if ((client->mode != IRECV_K_DFU_MODE) && (client->mode != IRECV_K_WTF_MODE) && (client->isKIS == 0)) {
2973 libusb_release_interface(client->handle, client->usb_interface); 3020 libusb_release_interface(client->handle, client->usb_interface);
2974 } 3021 }
2975 libusb_close(client->handle); 3022 libusb_close(client->handle);