diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/libirecovery.c | 120 |
1 files changed, 86 insertions, 34 deletions
diff --git a/src/libirecovery.c b/src/libirecovery.c index 7aeb205..8b90ac5 100644 --- a/src/libirecovery.c +++ b/src/libirecovery.c | |||
| @@ -386,8 +386,9 @@ irecv_error_t mobiledevice_connect(irecv_client_t* client, unsigned long long ec | |||
| 386 | irecv_close(_client); | 386 | irecv_close(_client); |
| 387 | return IRECV_E_UNABLE_TO_CONNECT; | 387 | return IRECV_E_UNABLE_TO_CONNECT; |
| 388 | } | 388 | } |
| 389 | 389 | ||
| 390 | *client = _client; | 390 | *client = _client; |
| 391 | |||
| 391 | return IRECV_E_SUCCESS; | 392 | return IRECV_E_SUCCESS; |
| 392 | } | 393 | } |
| 393 | 394 | ||
| @@ -396,6 +397,7 @@ irecv_error_t mobiledevice_openpipes(irecv_client_t client) { | |||
| 396 | irecv_close(client); | 397 | irecv_close(client); |
| 397 | return IRECV_E_UNABLE_TO_CONNECT; | 398 | return IRECV_E_UNABLE_TO_CONNECT; |
| 398 | } | 399 | } |
| 400 | |||
| 399 | if (client->DfuPath && !(client->hDFU = CreateFile(client->DfuPath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL))) { | 401 | if (client->DfuPath && !(client->hDFU = CreateFile(client->DfuPath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL))) { |
| 400 | irecv_close(client); | 402 | irecv_close(client); |
| 401 | return IRECV_E_UNABLE_TO_CONNECT; | 403 | return IRECV_E_UNABLE_TO_CONNECT; |
| @@ -413,12 +415,12 @@ irecv_error_t mobiledevice_openpipes(irecv_client_t client) { | |||
| 413 | } | 415 | } |
| 414 | client->handle = client->hIB; | 416 | client->handle = client->hIB; |
| 415 | } | 417 | } |
| 416 | 418 | ||
| 417 | if (client->mode == 0) { | 419 | if (client->mode == 0) { |
| 418 | irecv_close(client); | 420 | irecv_close(client); |
| 419 | return IRECV_E_UNABLE_TO_CONNECT; | 421 | return IRECV_E_UNABLE_TO_CONNECT; |
| 420 | } | 422 | } |
| 421 | 423 | ||
| 422 | return IRECV_E_SUCCESS; | 424 | return IRECV_E_SUCCESS; |
| 423 | } | 425 | } |
| 424 | 426 | ||
| @@ -476,9 +478,10 @@ int irecv_usb_control_transfer( irecv_client_t client, | |||
| 476 | DWORD ret; | 478 | DWORD ret; |
| 477 | BOOL bRet; | 479 | BOOL bRet; |
| 478 | OVERLAPPED overlapped; | 480 | OVERLAPPED overlapped; |
| 479 | 481 | ||
| 480 | if (data == NULL) wLength = 0; | 482 | if (data == NULL) |
| 481 | 483 | wLength = 0; | |
| 484 | |||
| 482 | usb_control_request* packet = (usb_control_request*) malloc(sizeof(usb_control_request) + wLength); | 485 | usb_control_request* packet = (usb_control_request*) malloc(sizeof(usb_control_request) + wLength); |
| 483 | packet->bmRequestType = bmRequestType; | 486 | packet->bmRequestType = bmRequestType; |
| 484 | packet->bRequest = bRequest; | 487 | packet->bRequest = bRequest; |
| @@ -489,7 +492,7 @@ int irecv_usb_control_transfer( irecv_client_t client, | |||
| 489 | if (bmRequestType < 0x80 && wLength > 0) { | 492 | if (bmRequestType < 0x80 && wLength > 0) { |
| 490 | memcpy(packet->data, data, wLength); | 493 | memcpy(packet->data, data, wLength); |
| 491 | } | 494 | } |
| 492 | 495 | ||
| 493 | memset(&overlapped, 0, sizeof(overlapped)); | 496 | memset(&overlapped, 0, sizeof(overlapped)); |
| 494 | overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); | 497 | overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); |
| 495 | DeviceIoControl(client->handle, 0x2200A0, packet, sizeof(usb_control_request) + wLength, packet, sizeof(usb_control_request) + wLength, NULL, &overlapped); | 498 | DeviceIoControl(client->handle, 0x2200A0, packet, sizeof(usb_control_request) + wLength, packet, sizeof(usb_control_request) + wLength, NULL, &overlapped); |
| @@ -501,7 +504,7 @@ int irecv_usb_control_transfer( irecv_client_t client, | |||
| 501 | free(packet); | 504 | free(packet); |
| 502 | return -1; | 505 | return -1; |
| 503 | } | 506 | } |
| 504 | 507 | ||
| 505 | count -= sizeof(usb_control_request); | 508 | count -= sizeof(usb_control_request); |
| 506 | if (count > 0) { | 509 | if (count > 0) { |
| 507 | if (bmRequestType >= 0x80) { | 510 | if (bmRequestType >= 0x80) { |
| @@ -509,6 +512,7 @@ int irecv_usb_control_transfer( irecv_client_t client, | |||
| 509 | } | 512 | } |
| 510 | } | 513 | } |
| 511 | free(packet); | 514 | free(packet); |
| 515 | |||
| 512 | return count; | 516 | return count; |
| 513 | #endif | 517 | #endif |
| 514 | } | 518 | } |
| @@ -550,7 +554,7 @@ static int irecv_get_string_descriptor_ascii(irecv_client_t client, uint8_t desc | |||
| 550 | memset(buffer, 0, size); | 554 | memset(buffer, 0, size); |
| 551 | 555 | ||
| 552 | ret = irecv_usb_control_transfer(client, 0x80, 0x06, (0x03 << 8) | desc_index, langid, data, sizeof(data), USB_TIMEOUT); | 556 | ret = irecv_usb_control_transfer(client, 0x80, 0x06, (0x03 << 8) | desc_index, langid, data, sizeof(data), USB_TIMEOUT); |
| 553 | 557 | ||
| 554 | if (ret < 0) return ret; | 558 | if (ret < 0) return ret; |
| 555 | if (data[1] != 0x03) return IRECV_E_UNKNOWN_ERROR; | 559 | if (data[1] != 0x03) return IRECV_E_UNKNOWN_ERROR; |
| 556 | if (data[0] > ret) return IRECV_E_UNKNOWN_ERROR; | 560 | if (data[0] > ret) return IRECV_E_UNKNOWN_ERROR; |
| @@ -565,7 +569,7 @@ static int irecv_get_string_descriptor_ascii(irecv_client_t client, uint8_t desc | |||
| 565 | } | 569 | } |
| 566 | } | 570 | } |
| 567 | buffer[di] = 0; | 571 | buffer[di] = 0; |
| 568 | 572 | ||
| 569 | return di; | 573 | return di; |
| 570 | #endif | 574 | #endif |
| 571 | } | 575 | } |
| @@ -674,6 +678,7 @@ irecv_error_t irecv_open_with_ecid(irecv_client_t* pclient, unsigned long long e | |||
| 674 | } | 678 | } |
| 675 | 679 | ||
| 676 | *pclient = client; | 680 | *pclient = client; |
| 681 | |||
| 677 | return IRECV_E_SUCCESS; | 682 | return IRECV_E_SUCCESS; |
| 678 | } | 683 | } |
| 679 | } | 684 | } |
| @@ -697,13 +702,15 @@ irecv_error_t irecv_open_with_ecid(irecv_client_t* pclient, unsigned long long e | |||
| 697 | debug("WARNING: set interface failed, error %d\n", error); | 702 | debug("WARNING: set interface failed, error %d\n", error); |
| 698 | } | 703 | } |
| 699 | } | 704 | } |
| 705 | |||
| 700 | return ret; | 706 | return ret; |
| 701 | #endif | 707 | #endif |
| 702 | } | 708 | } |
| 703 | 709 | ||
| 704 | irecv_error_t irecv_usb_set_configuration(irecv_client_t client, int configuration) { | 710 | irecv_error_t irecv_usb_set_configuration(irecv_client_t client, int configuration) { |
| 705 | if (check_context(client) != IRECV_E_SUCCESS) return IRECV_E_NO_DEVICE; | 711 | if (check_context(client) != IRECV_E_SUCCESS) |
| 706 | 712 | return IRECV_E_NO_DEVICE; | |
| 713 | |||
| 707 | #ifndef WIN32 | 714 | #ifndef WIN32 |
| 708 | debug("Setting to configuration %d\n", configuration); | 715 | debug("Setting to configuration %d\n", configuration); |
| 709 | 716 | ||
| @@ -722,7 +729,8 @@ irecv_error_t irecv_usb_set_configuration(irecv_client_t client, int configurati | |||
| 722 | } | 729 | } |
| 723 | 730 | ||
| 724 | irecv_error_t irecv_usb_set_interface(irecv_client_t client, int interface, int alt_interface) { | 731 | irecv_error_t irecv_usb_set_interface(irecv_client_t client, int interface, int alt_interface) { |
| 725 | if (check_context(client) != IRECV_E_SUCCESS) return IRECV_E_NO_DEVICE; | 732 | if (check_context(client) != IRECV_E_SUCCESS) |
| 733 | return IRECV_E_NO_DEVICE; | ||
| 726 | 734 | ||
| 727 | debug("Setting to interface %d:%d\n", interface, alt_interface); | 735 | debug("Setting to interface %d:%d\n", interface, alt_interface); |
| 728 | #ifndef WIN32 | 736 | #ifndef WIN32 |
| @@ -748,7 +756,8 @@ irecv_error_t irecv_usb_set_interface(irecv_client_t client, int interface, int | |||
| 748 | } | 756 | } |
| 749 | 757 | ||
| 750 | irecv_error_t irecv_reset(irecv_client_t client) { | 758 | irecv_error_t irecv_reset(irecv_client_t client) { |
| 751 | if (check_context(client) != IRECV_E_SUCCESS) return IRECV_E_NO_DEVICE; | 759 | if (check_context(client) != IRECV_E_SUCCESS) |
| 760 | return IRECV_E_NO_DEVICE; | ||
| 752 | 761 | ||
| 753 | #ifndef WIN32 | 762 | #ifndef WIN32 |
| 754 | libusb_reset_device(client->handle); | 763 | libusb_reset_device(client->handle); |
| @@ -774,7 +783,7 @@ irecv_error_t irecv_open_with_ecid_and_attempts(irecv_client_t* pclient, unsigne | |||
| 774 | sleep(1); | 783 | sleep(1); |
| 775 | } else { | 784 | } else { |
| 776 | return IRECV_E_SUCCESS; | 785 | return IRECV_E_SUCCESS; |
| 777 | } | 786 | } |
| 778 | } | 787 | } |
| 779 | 788 | ||
| 780 | return IRECV_E_UNABLE_TO_CONNECT; | 789 | return IRECV_E_UNABLE_TO_CONNECT; |
| @@ -900,7 +909,9 @@ static irecv_error_t irecv_send_command_raw(irecv_client_t client, const char* c | |||
| 900 | 909 | ||
| 901 | irecv_error_t irecv_send_command(irecv_client_t client, const char* command) { | 910 | irecv_error_t irecv_send_command(irecv_client_t client, const char* command) { |
| 902 | irecv_error_t error = 0; | 911 | irecv_error_t error = 0; |
| 903 | if (check_context(client) != IRECV_E_SUCCESS) return IRECV_E_NO_DEVICE; | 912 | |
| 913 | if (check_context(client) != IRECV_E_SUCCESS) | ||
| 914 | return IRECV_E_NO_DEVICE; | ||
| 904 | 915 | ||
| 905 | unsigned int length = strlen(command); | 916 | unsigned int length = strlen(command); |
| 906 | if (length >= 0x100) { | 917 | if (length >= 0x100) { |
| @@ -937,7 +948,8 @@ irecv_error_t irecv_send_command(irecv_client_t client, const char* command) { | |||
| 937 | } | 948 | } |
| 938 | 949 | ||
| 939 | irecv_error_t irecv_send_file(irecv_client_t client, const char* filename, int dfuNotifyFinished) { | 950 | irecv_error_t irecv_send_file(irecv_client_t client, const char* filename, int dfuNotifyFinished) { |
| 940 | if (check_context(client) != IRECV_E_SUCCESS) return IRECV_E_NO_DEVICE; | 951 | if (check_context(client) != IRECV_E_SUCCESS) |
| 952 | return IRECV_E_NO_DEVICE; | ||
| 941 | 953 | ||
| 942 | FILE* file = fopen(filename, "rb"); | 954 | FILE* file = fopen(filename, "rb"); |
| 943 | if (file == NULL) { | 955 | if (file == NULL) { |
| @@ -964,6 +976,7 @@ irecv_error_t irecv_send_file(irecv_client_t client, const char* filename, int d | |||
| 964 | 976 | ||
| 965 | irecv_error_t error = irecv_send_buffer(client, (unsigned char*)buffer, length, dfuNotifyFinished); | 977 | irecv_error_t error = irecv_send_buffer(client, (unsigned char*)buffer, length, dfuNotifyFinished); |
| 966 | free(buffer); | 978 | free(buffer); |
| 979 | |||
| 967 | return error; | 980 | return error; |
| 968 | } | 981 | } |
| 969 | 982 | ||
| @@ -981,19 +994,23 @@ static irecv_error_t irecv_get_status(irecv_client_t client, unsigned int* statu | |||
| 981 | } | 994 | } |
| 982 | 995 | ||
| 983 | *status = (unsigned int) buffer[4]; | 996 | *status = (unsigned int) buffer[4]; |
| 997 | |||
| 984 | return IRECV_E_SUCCESS; | 998 | return IRECV_E_SUCCESS; |
| 985 | } | 999 | } |
| 986 | 1000 | ||
| 987 | irecv_error_t irecv_send_buffer(irecv_client_t client, unsigned char* buffer, unsigned long length, int dfuNotifyFinished) { | 1001 | irecv_error_t irecv_send_buffer(irecv_client_t client, unsigned char* buffer, unsigned long length, int dfuNotifyFinished) { |
| 988 | irecv_error_t error = 0; | 1002 | irecv_error_t error = 0; |
| 989 | int recovery_mode = ((client->mode != IRECV_K_DFU_MODE) && (client->mode != IRECV_K_WTF_MODE)); | 1003 | int recovery_mode = ((client->mode != IRECV_K_DFU_MODE) && (client->mode != IRECV_K_WTF_MODE)); |
| 990 | if (check_context(client) != IRECV_E_SUCCESS) return IRECV_E_NO_DEVICE; | 1004 | |
| 1005 | if (check_context(client) != IRECV_E_SUCCESS) | ||
| 1006 | return IRECV_E_NO_DEVICE; | ||
| 991 | 1007 | ||
| 992 | unsigned int h1 = 0xFFFFFFFF; | 1008 | unsigned int h1 = 0xFFFFFFFF; |
| 993 | unsigned char dfu_xbuf[12] = {0xff, 0xff, 0xff, 0xff, 0xac, 0x05, 0x00, 0x01, 0x55, 0x46, 0x44, 0x10}; | 1009 | unsigned char dfu_xbuf[12] = {0xff, 0xff, 0xff, 0xff, 0xac, 0x05, 0x00, 0x01, 0x55, 0x46, 0x44, 0x10}; |
| 994 | int packet_size = recovery_mode ? 0x8000 : 0x800; | 1010 | int packet_size = recovery_mode ? 0x8000 : 0x800; |
| 995 | int last = length % packet_size; | 1011 | int last = length % packet_size; |
| 996 | int packets = length / packet_size; | 1012 | int packets = length / packet_size; |
| 1013 | |||
| 997 | if (last != 0) { | 1014 | if (last != 0) { |
| 998 | packets++; | 1015 | packets++; |
| 999 | } else { | 1016 | } else { |
| @@ -1011,6 +1028,7 @@ irecv_error_t irecv_send_buffer(irecv_client_t client, unsigned char* buffer, un | |||
| 1011 | error = IRECV_E_USB_UPLOAD; | 1028 | error = IRECV_E_USB_UPLOAD; |
| 1012 | } | 1029 | } |
| 1013 | } | 1030 | } |
| 1031 | |||
| 1014 | if (error != IRECV_E_SUCCESS) { | 1032 | if (error != IRECV_E_SUCCESS) { |
| 1015 | return error; | 1033 | return error; |
| 1016 | } | 1034 | } |
| @@ -1069,6 +1087,7 @@ irecv_error_t irecv_send_buffer(irecv_client_t client, unsigned char* buffer, un | |||
| 1069 | 1087 | ||
| 1070 | if (!recovery_mode && status != 5) { | 1088 | if (!recovery_mode && status != 5) { |
| 1071 | int retry = 0; | 1089 | int retry = 0; |
| 1090 | |||
| 1072 | while (retry < 20) { | 1091 | while (retry < 20) { |
| 1073 | irecv_get_status(client, &status); | 1092 | irecv_get_status(client, &status); |
| 1074 | if (status == 5) { | 1093 | if (status == 5) { |
| @@ -1076,6 +1095,7 @@ irecv_error_t irecv_send_buffer(irecv_client_t client, unsigned char* buffer, un | |||
| 1076 | } | 1095 | } |
| 1077 | sleep(1); | 1096 | sleep(1); |
| 1078 | } | 1097 | } |
| 1098 | |||
| 1079 | if (status != 5) { | 1099 | if (status != 5) { |
| 1080 | return IRECV_E_USB_UPLOAD; | 1100 | return IRECV_E_USB_UPLOAD; |
| 1081 | } | 1101 | } |
| @@ -1118,7 +1138,9 @@ irecv_error_t irecv_send_buffer(irecv_client_t client, unsigned char* buffer, un | |||
| 1118 | irecv_error_t irecv_receive(irecv_client_t client) { | 1138 | irecv_error_t irecv_receive(irecv_client_t client) { |
| 1119 | char buffer[BUFFER_SIZE]; | 1139 | char buffer[BUFFER_SIZE]; |
| 1120 | memset(buffer, '\0', BUFFER_SIZE); | 1140 | memset(buffer, '\0', BUFFER_SIZE); |
| 1121 | if (check_context(client) != IRECV_E_SUCCESS) return IRECV_E_NO_DEVICE; | 1141 | |
| 1142 | if (check_context(client) != IRECV_E_SUCCESS) | ||
| 1143 | return IRECV_E_NO_DEVICE; | ||
| 1122 | 1144 | ||
| 1123 | int bytes = 0; | 1145 | int bytes = 0; |
| 1124 | while (irecv_usb_bulk_transfer(client, 0x81, (unsigned char*) buffer, BUFFER_SIZE, &bytes, 500) == 0) { | 1146 | while (irecv_usb_bulk_transfer(client, 0x81, (unsigned char*) buffer, BUFFER_SIZE, &bytes, 500) == 0) { |
| @@ -1140,7 +1162,10 @@ irecv_error_t irecv_receive(irecv_client_t client) { | |||
| 1140 | 1162 | ||
| 1141 | irecv_error_t irecv_getenv(irecv_client_t client, const char* variable, char** value) { | 1163 | irecv_error_t irecv_getenv(irecv_client_t client, const char* variable, char** value) { |
| 1142 | char command[256]; | 1164 | char command[256]; |
| 1143 | if (check_context(client) != IRECV_E_SUCCESS) return IRECV_E_NO_DEVICE; | 1165 | |
| 1166 | if (check_context(client) != IRECV_E_SUCCESS) | ||
| 1167 | return IRECV_E_NO_DEVICE; | ||
| 1168 | |||
| 1144 | *value = NULL; | 1169 | *value = NULL; |
| 1145 | 1170 | ||
| 1146 | if(variable == NULL) { | 1171 | if(variable == NULL) { |
| @@ -1153,6 +1178,7 @@ irecv_error_t irecv_getenv(irecv_client_t client, const char* variable, char** v | |||
| 1153 | if(error == IRECV_E_PIPE) { | 1178 | if(error == IRECV_E_PIPE) { |
| 1154 | return IRECV_E_SUCCESS; | 1179 | return IRECV_E_SUCCESS; |
| 1155 | } | 1180 | } |
| 1181 | |||
| 1156 | if(error != IRECV_E_SUCCESS) { | 1182 | if(error != IRECV_E_SUCCESS) { |
| 1157 | return error; | 1183 | return error; |
| 1158 | } | 1184 | } |
| @@ -1171,7 +1197,9 @@ irecv_error_t irecv_getenv(irecv_client_t client, const char* variable, char** v | |||
| 1171 | } | 1197 | } |
| 1172 | 1198 | ||
| 1173 | irecv_error_t irecv_getret(irecv_client_t client, unsigned int* value) { | 1199 | irecv_error_t irecv_getret(irecv_client_t client, unsigned int* value) { |
| 1174 | if (check_context(client) != IRECV_E_SUCCESS) return IRECV_E_NO_DEVICE; | 1200 | if (check_context(client) != IRECV_E_SUCCESS) |
| 1201 | return IRECV_E_NO_DEVICE; | ||
| 1202 | |||
| 1175 | *value = 0; | 1203 | *value = 0; |
| 1176 | 1204 | ||
| 1177 | char* response = (char*) malloc(256); | 1205 | char* response = (char*) malloc(256); |
| @@ -1188,7 +1216,8 @@ irecv_error_t irecv_getret(irecv_client_t client, unsigned int* value) { | |||
| 1188 | } | 1216 | } |
| 1189 | 1217 | ||
| 1190 | irecv_error_t irecv_get_cpid(irecv_client_t client, unsigned int* cpid) { | 1218 | irecv_error_t irecv_get_cpid(irecv_client_t client, unsigned int* cpid) { |
| 1191 | if (check_context(client) != IRECV_E_SUCCESS) return IRECV_E_NO_DEVICE; | 1219 | if (check_context(client) != IRECV_E_SUCCESS) |
| 1220 | return IRECV_E_NO_DEVICE; | ||
| 1192 | 1221 | ||
| 1193 | if (client->mode == IRECV_K_WTF_MODE) { | 1222 | if (client->mode == IRECV_K_WTF_MODE) { |
| 1194 | char s_cpid[8] = {0,}; | 1223 | char s_cpid[8] = {0,}; |
| @@ -1197,6 +1226,7 @@ irecv_error_t irecv_get_cpid(irecv_client_t client, unsigned int* cpid) { | |||
| 1197 | *cpid = 0; | 1226 | *cpid = 0; |
| 1198 | return IRECV_E_UNKNOWN_ERROR; | 1227 | return IRECV_E_UNKNOWN_ERROR; |
| 1199 | } | 1228 | } |
| 1229 | |||
| 1200 | return IRECV_E_SUCCESS; | 1230 | return IRECV_E_SUCCESS; |
| 1201 | } | 1231 | } |
| 1202 | 1232 | ||
| @@ -1211,7 +1241,8 @@ irecv_error_t irecv_get_cpid(irecv_client_t client, unsigned int* cpid) { | |||
| 1211 | } | 1241 | } |
| 1212 | 1242 | ||
| 1213 | irecv_error_t irecv_get_bdid(irecv_client_t client, unsigned int* bdid) { | 1243 | irecv_error_t irecv_get_bdid(irecv_client_t client, unsigned int* bdid) { |
| 1214 | if (check_context(client) != IRECV_E_SUCCESS) return IRECV_E_NO_DEVICE; | 1244 | if (check_context(client) != IRECV_E_SUCCESS) |
| 1245 | return IRECV_E_NO_DEVICE; | ||
| 1215 | 1246 | ||
| 1216 | char* bdid_string = strstr(client->serial, "BDID:"); | 1247 | char* bdid_string = strstr(client->serial, "BDID:"); |
| 1217 | if (bdid_string == NULL) { | 1248 | if (bdid_string == NULL) { |
| @@ -1224,7 +1255,8 @@ irecv_error_t irecv_get_bdid(irecv_client_t client, unsigned int* bdid) { | |||
| 1224 | } | 1255 | } |
| 1225 | 1256 | ||
| 1226 | irecv_error_t irecv_get_ecid(irecv_client_t client, unsigned long long* ecid) { | 1257 | irecv_error_t irecv_get_ecid(irecv_client_t client, unsigned long long* ecid) { |
| 1227 | if (check_context(client) != IRECV_E_SUCCESS) return IRECV_E_NO_DEVICE; | 1258 | if (check_context(client) != IRECV_E_SUCCESS) |
| 1259 | return IRECV_E_NO_DEVICE; | ||
| 1228 | 1260 | ||
| 1229 | char* ecid_string = strstr(client->serial, "ECID:"); | 1261 | char* ecid_string = strstr(client->serial, "ECID:"); |
| 1230 | if (ecid_string == NULL) { | 1262 | if (ecid_string == NULL) { |
| @@ -1237,7 +1269,8 @@ irecv_error_t irecv_get_ecid(irecv_client_t client, unsigned long long* ecid) { | |||
| 1237 | } | 1269 | } |
| 1238 | 1270 | ||
| 1239 | irecv_error_t irecv_get_srnm(irecv_client_t client, char* srnm) { | 1271 | irecv_error_t irecv_get_srnm(irecv_client_t client, char* srnm) { |
| 1240 | if (check_context(client) != IRECV_E_SUCCESS) return IRECV_E_NO_DEVICE; | 1272 | if (check_context(client) != IRECV_E_SUCCESS) |
| 1273 | return IRECV_E_NO_DEVICE; | ||
| 1241 | 1274 | ||
| 1242 | char* srnmp; | 1275 | char* srnmp; |
| 1243 | char* srnm_string = strstr(client->serial, "SRNM:["); | 1276 | char* srnm_string = strstr(client->serial, "SRNM:["); |
| @@ -1256,7 +1289,8 @@ irecv_error_t irecv_get_srnm(irecv_client_t client, char* srnm) { | |||
| 1256 | } | 1289 | } |
| 1257 | 1290 | ||
| 1258 | irecv_error_t irecv_get_imei(irecv_client_t client, char* imei) { | 1291 | irecv_error_t irecv_get_imei(irecv_client_t client, char* imei) { |
| 1259 | if (check_context(client) != IRECV_E_SUCCESS) return IRECV_E_NO_DEVICE; | 1292 | if (check_context(client) != IRECV_E_SUCCESS) |
| 1293 | return IRECV_E_NO_DEVICE; | ||
| 1260 | 1294 | ||
| 1261 | char* imeip; | 1295 | char* imeip; |
| 1262 | char* imei_string = strstr(client->serial, "IMEI:["); | 1296 | char* imei_string = strstr(client->serial, "IMEI:["); |
| @@ -1276,7 +1310,8 @@ irecv_error_t irecv_get_imei(irecv_client_t client, char* imei) { | |||
| 1276 | } | 1310 | } |
| 1277 | 1311 | ||
| 1278 | irecv_error_t irecv_get_nonce(irecv_client_t client, unsigned char** nonce, int* nonce_size) { | 1312 | irecv_error_t irecv_get_nonce(irecv_client_t client, unsigned char** nonce, int* nonce_size) { |
| 1279 | if (check_context(client) != IRECV_E_SUCCESS) return IRECV_E_NO_DEVICE; | 1313 | if (check_context(client) != IRECV_E_SUCCESS) |
| 1314 | return IRECV_E_NO_DEVICE; | ||
| 1280 | 1315 | ||
| 1281 | unsigned char buf[255]; | 1316 | unsigned char buf[255]; |
| 1282 | int len; | 1317 | int len; |
| @@ -1329,17 +1364,22 @@ irecv_error_t irecv_get_nonce(irecv_client_t client, unsigned char** nonce, int* | |||
| 1329 | } | 1364 | } |
| 1330 | 1365 | ||
| 1331 | irecv_error_t irecv_trigger_limera1n_exploit(irecv_client_t client) { | 1366 | irecv_error_t irecv_trigger_limera1n_exploit(irecv_client_t client) { |
| 1332 | if (check_context(client) != IRECV_E_SUCCESS) return IRECV_E_NO_DEVICE; | 1367 | if (check_context(client) != IRECV_E_SUCCESS) |
| 1368 | return IRECV_E_NO_DEVICE; | ||
| 1369 | |||
| 1333 | irecv_usb_control_transfer(client, 0x21, 2, 0, 0, NULL, 0, USB_TIMEOUT); | 1370 | irecv_usb_control_transfer(client, 0x21, 2, 0, 0, NULL, 0, USB_TIMEOUT); |
| 1371 | |||
| 1334 | return IRECV_E_SUCCESS; | 1372 | return IRECV_E_SUCCESS; |
| 1335 | } | 1373 | } |
| 1336 | 1374 | ||
| 1337 | irecv_error_t irecv_execute_script(irecv_client_t client, const char* script) { | 1375 | irecv_error_t irecv_execute_script(irecv_client_t client, const char* script) { |
| 1338 | irecv_error_t error = IRECV_E_SUCCESS; | 1376 | irecv_error_t error = IRECV_E_SUCCESS; |
| 1339 | if (check_context(client) != IRECV_E_SUCCESS) return IRECV_E_NO_DEVICE; | 1377 | if (check_context(client) != IRECV_E_SUCCESS) |
| 1378 | return IRECV_E_NO_DEVICE; | ||
| 1340 | 1379 | ||
| 1341 | char* body = strdup(script); | 1380 | char* body = strdup(script); |
| 1342 | char* line = strtok(body, "\n"); | 1381 | char* line = strtok(body, "\n"); |
| 1382 | |||
| 1343 | while(line != NULL) { | 1383 | while(line != NULL) { |
| 1344 | if(line[0] != '#') { | 1384 | if(line[0] != '#') { |
| 1345 | error = irecv_send_command(client, line); | 1385 | error = irecv_send_command(client, line); |
| @@ -1366,12 +1406,15 @@ irecv_error_t irecv_saveenv(irecv_client_t client) { | |||
| 1366 | if(error != IRECV_E_SUCCESS) { | 1406 | if(error != IRECV_E_SUCCESS) { |
| 1367 | return error; | 1407 | return error; |
| 1368 | } | 1408 | } |
| 1409 | |||
| 1369 | return IRECV_E_SUCCESS; | 1410 | return IRECV_E_SUCCESS; |
| 1370 | } | 1411 | } |
| 1371 | 1412 | ||
| 1372 | irecv_error_t irecv_setenv(irecv_client_t client, const char* variable, const char* value) { | 1413 | irecv_error_t irecv_setenv(irecv_client_t client, const char* variable, const char* value) { |
| 1373 | char command[256]; | 1414 | char command[256]; |
| 1374 | if (check_context(client) != IRECV_E_SUCCESS) return IRECV_E_NO_DEVICE; | 1415 | |
| 1416 | if (check_context(client) != IRECV_E_SUCCESS) | ||
| 1417 | return IRECV_E_NO_DEVICE; | ||
| 1375 | 1418 | ||
| 1376 | if(variable == NULL || value == NULL) { | 1419 | if(variable == NULL || value == NULL) { |
| 1377 | return IRECV_E_UNKNOWN_ERROR; | 1420 | return IRECV_E_UNKNOWN_ERROR; |
| @@ -1392,6 +1435,7 @@ irecv_error_t irecv_reboot(irecv_client_t client) { | |||
| 1392 | if(error != IRECV_E_SUCCESS) { | 1435 | if(error != IRECV_E_SUCCESS) { |
| 1393 | return error; | 1436 | return error; |
| 1394 | } | 1437 | } |
| 1438 | |||
| 1395 | return IRECV_E_SUCCESS; | 1439 | return IRECV_E_SUCCESS; |
| 1396 | } | 1440 | } |
| 1397 | 1441 | ||
| @@ -1441,17 +1485,21 @@ const char* irecv_strerror(irecv_error_t error) { | |||
| 1441 | } | 1485 | } |
| 1442 | 1486 | ||
| 1443 | irecv_error_t irecv_reset_counters(irecv_client_t client) { | 1487 | irecv_error_t irecv_reset_counters(irecv_client_t client) { |
| 1444 | if (check_context(client) != IRECV_E_SUCCESS) return IRECV_E_NO_DEVICE; | 1488 | if (check_context(client) != IRECV_E_SUCCESS) |
| 1489 | return IRECV_E_NO_DEVICE; | ||
| 1490 | |||
| 1445 | if ((client->mode == IRECV_K_DFU_MODE) || (client->mode == IRECV_K_WTF_MODE)) { | 1491 | if ((client->mode == IRECV_K_DFU_MODE) || (client->mode == IRECV_K_WTF_MODE)) { |
| 1446 | irecv_usb_control_transfer(client, 0x21, 4, 0, 0, 0, 0, USB_TIMEOUT); | 1492 | irecv_usb_control_transfer(client, 0x21, 4, 0, 0, 0, 0, USB_TIMEOUT); |
| 1447 | } | 1493 | } |
| 1494 | |||
| 1448 | return IRECV_E_SUCCESS; | 1495 | return IRECV_E_SUCCESS; |
| 1449 | } | 1496 | } |
| 1450 | 1497 | ||
| 1451 | irecv_error_t irecv_recv_buffer(irecv_client_t client, char* buffer, unsigned long length) { | 1498 | irecv_error_t irecv_recv_buffer(irecv_client_t client, char* buffer, unsigned long length) { |
| 1452 | int recovery_mode = ((client->mode != IRECV_K_DFU_MODE) && (client->mode != IRECV_K_WTF_MODE)); | 1499 | int recovery_mode = ((client->mode != IRECV_K_DFU_MODE) && (client->mode != IRECV_K_WTF_MODE)); |
| 1453 | 1500 | ||
| 1454 | if (check_context(client) != IRECV_E_SUCCESS) return IRECV_E_NO_DEVICE; | 1501 | if (check_context(client) != IRECV_E_SUCCESS) |
| 1502 | return IRECV_E_NO_DEVICE; | ||
| 1455 | 1503 | ||
| 1456 | int packet_size = recovery_mode ? 0x2000: 0x800; | 1504 | int packet_size = recovery_mode ? 0x2000: 0x800; |
| 1457 | int last = length % packet_size; | 1505 | int last = length % packet_size; |
| @@ -1468,7 +1516,7 @@ irecv_error_t irecv_recv_buffer(irecv_client_t client, char* buffer, unsigned lo | |||
| 1468 | for (i = 0; i < packets; i++) { | 1516 | for (i = 0; i < packets; i++) { |
| 1469 | unsigned short size = (i+1) < packets ? packet_size : last; | 1517 | unsigned short size = (i+1) < packets ? packet_size : last; |
| 1470 | bytes = irecv_usb_control_transfer(client, 0xA1, 2, 0, 0, (unsigned char*)&buffer[i * packet_size], size, USB_TIMEOUT); | 1518 | bytes = irecv_usb_control_transfer(client, 0xA1, 2, 0, 0, (unsigned char*)&buffer[i * packet_size], size, USB_TIMEOUT); |
| 1471 | 1519 | ||
| 1472 | if (bytes != size) { | 1520 | if (bytes != size) { |
| 1473 | return IRECV_E_USB_UPLOAD; | 1521 | return IRECV_E_USB_UPLOAD; |
| 1474 | } | 1522 | } |
| @@ -1493,14 +1541,17 @@ irecv_error_t irecv_finish_transfer(irecv_client_t client) { | |||
| 1493 | int i = 0; | 1541 | int i = 0; |
| 1494 | unsigned int status = 0; | 1542 | unsigned int status = 0; |
| 1495 | 1543 | ||
| 1496 | if (check_context(client) != IRECV_E_SUCCESS) return IRECV_E_NO_DEVICE; | 1544 | if (check_context(client) != IRECV_E_SUCCESS) |
| 1545 | return IRECV_E_NO_DEVICE; | ||
| 1497 | 1546 | ||
| 1498 | irecv_usb_control_transfer(client, 0x21, 1, 0, 0, 0, 0, USB_TIMEOUT); | 1547 | irecv_usb_control_transfer(client, 0x21, 1, 0, 0, 0, 0, USB_TIMEOUT); |
| 1499 | 1548 | ||
| 1500 | for(i = 0; i < 3; i++){ | 1549 | for(i = 0; i < 3; i++){ |
| 1501 | irecv_get_status(client, &status); | 1550 | irecv_get_status(client, &status); |
| 1502 | } | 1551 | } |
| 1552 | |||
| 1503 | irecv_reset(client); | 1553 | irecv_reset(client); |
| 1554 | |||
| 1504 | return IRECV_E_SUCCESS; | 1555 | return IRECV_E_SUCCESS; |
| 1505 | } | 1556 | } |
| 1506 | 1557 | ||
| @@ -1582,5 +1633,6 @@ irecv_client_t irecv_reconnect(irecv_client_t client, int initial_pause) { | |||
| 1582 | } | 1633 | } |
| 1583 | 1634 | ||
| 1584 | new_client->progress_callback = progress_callback; | 1635 | new_client->progress_callback = progress_callback; |
| 1636 | |||
| 1585 | return new_client; | 1637 | return new_client; |
| 1586 | } | 1638 | } |
