diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/irecovery.c | 24 | ||||
| -rw-r--r-- | src/libirecovery.c | 77 |
2 files changed, 73 insertions, 28 deletions
diff --git a/src/irecovery.c b/src/irecovery.c index 1c4957e..56b0453 100644 --- a/src/irecovery.c +++ b/src/irecovery.c | |||
| @@ -52,8 +52,10 @@ void parse_command(irecv_device_t* device, unsigned char* command, unsigned int | |||
| 52 | } else | 52 | } else |
| 53 | 53 | ||
| 54 | if(!strcmp(cmd, "/reconnect")) { | 54 | if(!strcmp(cmd, "/reconnect")) { |
| 55 | char* uuid = strdup(device->uuid); | ||
| 55 | irecv_close(device); | 56 | irecv_close(device); |
| 56 | irecv_open(device); | 57 | irecv_open(device, uuid); |
| 58 | free(uuid); | ||
| 57 | } else | 59 | } else |
| 58 | 60 | ||
| 59 | if(!strcmp(cmd, "/upload")) { | 61 | if(!strcmp(cmd, "/upload")) { |
| @@ -151,6 +153,7 @@ void print_usage() { | |||
| 151 | printf("iRecovery - iDevice Recovery Utility\n"); | 153 | printf("iRecovery - iDevice Recovery Utility\n"); |
| 152 | printf("Usage: ./irecovery [args]\n"); | 154 | printf("Usage: ./irecovery [args]\n"); |
| 153 | printf("\t-v\t\tStart irecovery in verbose mode.\n"); | 155 | printf("\t-v\t\tStart irecovery in verbose mode.\n"); |
| 156 | printf("\t-u <uuid>\ttarget specific device by its 40-digit device UUID\n"); | ||
| 154 | printf("\t-c <cmd>\tSend command to device.\n"); | 157 | printf("\t-c <cmd>\tSend command to device.\n"); |
| 155 | printf("\t-f <file>\tSend file to device.\n"); | 158 | printf("\t-f <file>\tSend file to device.\n"); |
| 156 | printf("\t-h\t\tShow this help.\n"); | 159 | printf("\t-h\t\tShow this help.\n"); |
| @@ -163,9 +166,10 @@ int main(int argc, char** argv) { | |||
| 163 | int opt = 0; | 166 | int opt = 0; |
| 164 | int action = 0; | 167 | int action = 0; |
| 165 | char* argument = NULL; | 168 | char* argument = NULL; |
| 169 | char *uuid = NULL; | ||
| 166 | irecv_error_t error = 0; | 170 | irecv_error_t error = 0; |
| 167 | if(argc == 1) print_usage(); | 171 | if(argc == 1) print_usage(); |
| 168 | while ((opt = getopt(argc, argv, "vhrsc:f:")) > 0) { | 172 | while ((opt = getopt(argc, argv, "vhru:sc:f:")) > 0) { |
| 169 | switch (opt) { | 173 | switch (opt) { |
| 170 | case 'v': | 174 | case 'v': |
| 171 | verbose += 1; | 175 | verbose += 1; |
| @@ -179,6 +183,10 @@ int main(int argc, char** argv) { | |||
| 179 | action = kResetDevice; | 183 | action = kResetDevice; |
| 180 | break; | 184 | break; |
| 181 | 185 | ||
| 186 | case 'u': | ||
| 187 | uuid = optarg; | ||
| 188 | break; | ||
| 189 | |||
| 182 | case 's': | 190 | case 's': |
| 183 | action = kStartShell; | 191 | action = kStartShell; |
| 184 | break; | 192 | break; |
| @@ -195,7 +203,7 @@ int main(int argc, char** argv) { | |||
| 195 | 203 | ||
| 196 | default: | 204 | default: |
| 197 | fprintf(stderr, "Unknown argument\n"); | 205 | fprintf(stderr, "Unknown argument\n"); |
| 198 | break; | 206 | return -1; |
| 199 | } | 207 | } |
| 200 | } | 208 | } |
| 201 | 209 | ||
| @@ -209,14 +217,16 @@ int main(int argc, char** argv) { | |||
| 209 | int i = 0; | 217 | int i = 0; |
| 210 | for(i = 0; i <= 5; i++) { | 218 | for(i = 0; i <= 5; i++) { |
| 211 | debug("Attempting to connect... "); | 219 | debug("Attempting to connect... "); |
| 220 | |||
| 221 | if(irecv_open(device, uuid) < 0) sleep(1); | ||
| 222 | else break; | ||
| 223 | |||
| 224 | debug("failed. No recovery device found.\n"); | ||
| 225 | |||
| 212 | if(i == 5) { | 226 | if(i == 5) { |
| 213 | irecv_exit(device); | 227 | irecv_exit(device); |
| 214 | return -1; | 228 | return -1; |
| 215 | } | 229 | } |
| 216 | |||
| 217 | if(irecv_open(device) < 0) sleep(1); | ||
| 218 | else break; | ||
| 219 | debug("failed\n"); | ||
| 220 | } | 230 | } |
| 221 | 231 | ||
| 222 | switch(action) { | 232 | switch(action) { |
diff --git a/src/libirecovery.c b/src/libirecovery.c index b8eb224..18097ee 100644 --- a/src/libirecovery.c +++ b/src/libirecovery.c | |||
| @@ -58,9 +58,10 @@ irecv_device_t* irecv_init() { | |||
| 58 | return device; | 58 | return device; |
| 59 | } | 59 | } |
| 60 | 60 | ||
| 61 | irecv_error_t irecv_open(irecv_device_t* device) { | 61 | irecv_error_t irecv_open(irecv_device_t* device, const char *uuid) { |
| 62 | int i = 0; | 62 | int i = 0; |
| 63 | int usb_device_count = 0; | 63 | int usb_device_count = 0; |
| 64 | char serial[256]; | ||
| 64 | struct libusb_device* usb_device = NULL; | 65 | struct libusb_device* usb_device = NULL; |
| 65 | struct libusb_device** usb_device_list = NULL; | 66 | struct libusb_device** usb_device_list = NULL; |
| 66 | struct libusb_device_handle* usb_handle = NULL; | 67 | struct libusb_device_handle* usb_handle = NULL; |
| @@ -75,28 +76,58 @@ irecv_error_t irecv_open(irecv_device_t* device) { | |||
| 75 | for (i = 0; i < usb_device_count; i++) { | 76 | for (i = 0; i < usb_device_count; i++) { |
| 76 | usb_device = usb_device_list[i]; | 77 | usb_device = usb_device_list[i]; |
| 77 | libusb_get_device_descriptor(usb_device, &usb_descriptor); | 78 | libusb_get_device_descriptor(usb_device, &usb_descriptor); |
| 78 | if (usb_descriptor.idVendor == kAppleId) { | 79 | if (usb_descriptor.idVendor == APPLE_VENDOR_ID) { |
| 80 | /* verify this device is in a mode we understand */ | ||
| 81 | if (usb_descriptor.idProduct == kRecoveryMode1 || | ||
| 82 | usb_descriptor.idProduct == kRecoveryMode2 || | ||
| 83 | usb_descriptor.idProduct == kRecoveryMode3 || | ||
| 84 | usb_descriptor.idProduct == kRecoveryMode4 || | ||
| 85 | usb_descriptor.idProduct == kDfuMode) { | ||
| 86 | |||
| 87 | libusb_open(usb_device, &usb_handle); | ||
| 88 | if (usb_handle == NULL) { | ||
| 89 | libusb_free_device_list(usb_device_list, 1); | ||
| 90 | return IRECV_ERROR_UNABLE_TO_CONNECT; | ||
| 91 | } | ||
| 92 | |||
| 93 | /* get serial number */ | ||
| 94 | if (libusb_get_string_descriptor_ascii (usb_handle, usb_descriptor.iSerialNumber, serial, sizeof(serial)) < 0) { | ||
| 95 | libusb_free_device_list(usb_device_list, 1); | ||
| 96 | libusb_close(usb_handle); | ||
| 97 | return IRECV_ERROR_UNABLE_TO_CONNECT; | ||
| 98 | } | ||
| 99 | |||
| 100 | /* match uuid if required */ | ||
| 101 | if (uuid != NULL) { | ||
| 102 | if (strcmp(uuid, serial)) { | ||
| 103 | libusb_close(usb_handle); | ||
| 104 | continue; | ||
| 105 | } | ||
| 106 | } | ||
| 79 | 107 | ||
| 80 | libusb_open(usb_device, &usb_handle); | 108 | /* identified a valid recovery device */ |
| 81 | if (usb_handle == NULL) { | ||
| 82 | libusb_free_device_list(usb_device_list, 1); | 109 | libusb_free_device_list(usb_device_list, 1); |
| 83 | return IRECV_ERROR_UNABLE_TO_CONNECT; | 110 | |
| 84 | } | 111 | device->handle = usb_handle; |
| 85 | libusb_free_device_list(usb_device_list, 1); | 112 | device->uuid = strdup(serial); |
| 86 | 113 | device->mode = (irecv_mode_t) usb_descriptor.idProduct; | |
| 87 | device->handle = usb_handle; | 114 | |
| 88 | device->mode = (irecv_mode_t) usb_descriptor.idProduct; | 115 | debug("opening UUID \"%s\"... ", device->uuid); |
| 89 | error = irecv_set_configuration(device, 1); | 116 | |
| 90 | if(error != IRECV_SUCCESS) { | 117 | error = irecv_set_configuration(device, 1); |
| 91 | return error; | 118 | if(error != IRECV_SUCCESS) { |
| 92 | } | 119 | debug("setting configuration... "); |
| 93 | 120 | return error; | |
| 94 | error = irecv_set_interface(device, 1, 1); | 121 | } |
| 95 | if(error != IRECV_SUCCESS) { | 122 | |
| 96 | return error; | 123 | error = irecv_set_interface(device, 1, 1); |
| 124 | if(error != IRECV_SUCCESS) { | ||
| 125 | debug("setting interface... "); | ||
| 126 | return error; | ||
| 127 | } | ||
| 128 | |||
| 129 | return IRECV_SUCCESS; | ||
| 97 | } | 130 | } |
| 98 | |||
| 99 | return IRECV_SUCCESS; | ||
| 100 | } | 131 | } |
| 101 | } | 132 | } |
| 102 | 133 | ||
| @@ -158,7 +189,11 @@ irecv_error_t irecv_close(irecv_device_t* device) { | |||
| 158 | libusb_close(device->handle); | 189 | libusb_close(device->handle); |
| 159 | device->handle = NULL; | 190 | device->handle = NULL; |
| 160 | } | 191 | } |
| 161 | 192 | ||
| 193 | if(device->uuid != NULL) { | ||
| 194 | free(device->uuid); | ||
| 195 | } | ||
| 196 | |||
| 162 | return IRECV_SUCCESS; | 197 | return IRECV_SUCCESS; |
| 163 | } | 198 | } |
| 164 | 199 | ||
