diff options
author | Joshua Hill | 2010-06-22 15:06:55 -0400 |
---|---|---|
committer | Joshua Hill | 2010-06-22 15:06:55 -0400 |
commit | 38c965c16625d26915b3d4998a8a7e790c834d89 (patch) | |
tree | 227333a4a327c66b23cad380ee8c9614c315aa5f /src/recovery.c | |
parent | 61db8cf5abc37ea0da1878961f209f3eb2ba31bf (diff) | |
download | idevicerestore-38c965c16625d26915b3d4998a8a7e790c834d89.tar.gz idevicerestore-38c965c16625d26915b3d4998a8a7e790c834d89.tar.bz2 |
Reverted rcg4u merge, didn't realize this was actually from posixninja branch
Diffstat (limited to 'src/recovery.c')
-rw-r--r-- | src/recovery.c | 345 |
1 files changed, 118 insertions, 227 deletions
diff --git a/src/recovery.c b/src/recovery.c index 52f4802..4e2e7ad 100644 --- a/src/recovery.c +++ b/src/recovery.c @@ -23,356 +23,247 @@ #include <stdlib.h> #include <stdint.h> #include <libirecovery.h> -#include <libimobiledevice/restore.h> -#include <libimobiledevice/libimobiledevice.h> #include "tss.h" #include "img3.h" #include "recovery.h" #include "idevicerestore.h" -int recovery_progress_callback(irecv_client_t client, const irecv_event_t* event) { - if (event->type == IRECV_PROGRESS) { - print_progress_bar(event->data, event->progress); - } - return 0; -} - -int recovery_check_mode() { - irecv_client_t recovery = NULL; - irecv_error_t recovery_error = IRECV_E_SUCCESS; - - recovery_error = irecv_open(&recovery); - if (recovery_error != IRECV_E_SUCCESS) { - return -1; - } - - if (recovery->mode == kDfuMode) { - irecv_close(recovery); - return -1; - } - - irecv_close(recovery); - recovery = NULL; - return 0; -} - -int recovery_enter_restore(const char* uuid, const char* ipsw, plist_t tss) { - idevice_t device = NULL; - restored_client_t restore = NULL; - - // upload data to make device boot restore mode - if (recovery_send_ibec(ipsw, tss) < 0) { - error("ERROR: Unable to send iBEC\n"); - return -1; - } - sleep(1); - - if (recovery_send_applelogo(ipsw, tss) < 0) { - error("ERROR: Unable to send AppleLogo\n"); - return -1; - } - - if (recovery_send_devicetree(ipsw, tss) < 0) { - error("ERROR: Unable to send DeviceTree\n"); - return -1; - } - - if (recovery_send_ramdisk(ipsw, tss) < 0) { - error("ERROR: Unable to send Ramdisk\n"); - return -1; - } - - // for some reason iboot requires a hard reset after ramdisk - // or things start getting wacky - printf("Please unplug your device, then plug it back in\n"); - printf("Hit any key to continue..."); - getchar(); - - if (recovery_send_kernelcache(ipsw, tss) < 0) { - error("ERROR: Unable to send KernelCache\n"); - return -1; - } - - info("Waiting for device to enter restore mode\n"); - if (restore_open_with_timeout(uuid, &device, &restore) < 0) { - error("ERROR: Unable to connect to device in restore mode\n"); - return -1; - } - - restore_close(device, restore); - idevicerestore_mode = MODE_RESTORE; - return 0; -} - -int recovery_send_signed_component(irecv_client_t client, const char* ipsw, plist_t tss, char* component) { +int recovery_send_signed_component(irecv_client_t client, char* ipsw, plist_t tss, char* component) { int size = 0; char* data = NULL; char* path = NULL; char* blob = NULL; + img3_file* img3 = NULL; irecv_error_t error = 0; - if (tss_get_entry_path(tss, component, &path) < 0) { - error("ERROR: Unable to get component path\n"); - return -1; - } - - if (get_signed_component(ipsw, tss, path, &data, &size) < 0) { + if (get_signed_component_by_name(ipsw, tss, component, &data, &size) < 0) { error("ERROR: Unable to get signed component: %s\n", component); - free(path); return -1; } - free(path); info("Sending %s...\n", component); error = irecv_send_buffer(client, data, size); if (error != IRECV_E_SUCCESS) { - error("ERROR: Unable to send component: %s\n", component); + error("ERROR: Unable to send IMG3: %s\n", path); + img3_free(img3); free(data); + free(path); return -1; } - free(data); + + if (data) { + free(data); + data = NULL; + } return 0; } -int recovery_open_with_timeout(irecv_client_t* client) { +irecv_error_t recovery_open_with_timeout(irecv_client_t* client) { int i = 0; - int attempts = 10; - irecv_client_t recovery = NULL; - irecv_error_t recovery_error = IRECV_E_UNKNOWN_ERROR; - - for (i = 1; i <= attempts; i++) { - recovery_error = irecv_open(&recovery); - if (recovery_error == IRECV_E_SUCCESS) { - break; - } - - if (i >= attempts) { - error("ERROR: Unable to connect to device in recovery mode\n"); - return -1; + irecv_error_t error = 0; + for (i = 10; i > 0; i--) { + error = irecv_open(client); + if (error == IRECV_E_SUCCESS) { + return error; } sleep(2); - debug("Retrying connection...\n"); + info("Retrying connection...\n"); } - irecv_event_subscribe(recovery, IRECV_PROGRESS, &recovery_progress_callback, NULL); - *client = recovery; - return 0; + error("ERROR: Unable to connect to recovery device.\n"); + return error; } -int recovery_send_ibec(const char* ipsw, plist_t tss) { - irecv_client_t recovery = NULL; - const char* component = "iBEC"; - irecv_error_t recovery_error = IRECV_E_SUCCESS; +int recovery_send_ibec(char* ipsw, plist_t tss) { + irecv_error_t error = 0; + irecv_client_t client = NULL; + char* component = "iBEC"; - if (recovery_open_with_timeout(&recovery) < 0) { + error = recovery_open_with_timeout(&client); + if (error != IRECV_E_SUCCESS) { return -1; } - recovery_error = irecv_send_command(recovery, "setenv auto-boot true"); - if (recovery_error != IRECV_E_SUCCESS) { + error = irecv_send_command(client, "setenv auto-boot true"); + if (error != IRECV_E_SUCCESS) { error("ERROR: Unable to set auto-boot environmental variable\n"); - irecv_close(recovery); + irecv_close(client); + client = NULL; return -1; } - recovery_error = irecv_send_command(recovery, "saveenv"); - if (recovery_error != IRECV_E_SUCCESS) { + error = irecv_send_command(client, "saveenv"); + if (error != IRECV_E_SUCCESS) { error("ERROR: Unable to save environmental variable\n"); - irecv_close(recovery); + irecv_close(client); + client = NULL; return -1; } - if (recovery_send_signed_component(recovery, ipsw, tss, "iBEC") < 0) { + if (recovery_send_signed_component(client, ipsw, tss, component) < 0) { error("ERROR: Unable to send %s to device.\n", component); - irecv_close(recovery); + irecv_close(client); + client = NULL; return -1; } - recovery_error = irecv_send_command(recovery, "go"); - if (recovery_error != IRECV_E_SUCCESS) { + error = irecv_send_command(client, "go"); + if (error != IRECV_E_SUCCESS) { error("ERROR: Unable to execute %s\n", component); - irecv_close(recovery); + irecv_close(client); + client = NULL; return -1; } - irecv_close(recovery); - recovery = NULL; + if (client) { + irecv_close(client); + client = NULL; + } return 0; } -int recovery_send_applelogo(const char* ipsw, plist_t tss) { - irecv_client_t recovery = NULL; - const char* component = "applelogo"; - irecv_error_t recovery_error = IRECV_E_SUCCESS; +int recovery_send_applelogo(char* ipsw, plist_t tss) { + irecv_error_t error = 0; + irecv_client_t client = NULL; + char* component = "AppleLogo"; info("Sending %s...\n", component); - if (recovery_open_with_timeout(&recovery) < 0) { + + error = recovery_open_with_timeout(&client); + if (error != IRECV_E_SUCCESS) { return -1; } - if (recovery_send_signed_component(recovery, ipsw, tss, "AppleLogo") < 0) { + if (recovery_send_signed_component(client, ipsw, tss, component) < 0) { error("ERROR: Unable to send %s to device.\n", component); - irecv_close(recovery); + irecv_close(client); + client = NULL; return -1; } - recovery_error = irecv_send_command(recovery, "setpicture 1"); - if (recovery_error != IRECV_E_SUCCESS) { + error = irecv_send_command(client, "setpicture 1"); + if (error != IRECV_E_SUCCESS) { error("ERROR: Unable to set %s\n", component); - irecv_close(recovery); + irecv_close(client); + client = NULL; return -1; } - recovery_error = irecv_send_command(recovery, "bgcolor 0 0 0"); - if (recovery_error != IRECV_E_SUCCESS) { + error = irecv_send_command(client, "bgcolor 0 0 0"); + if (error != IRECV_E_SUCCESS) { error("ERROR: Unable to display %s\n", component); - irecv_close(recovery); + irecv_close(client); + client = NULL; return -1; } - irecv_close(recovery); - recovery = NULL; + if (client) { + irecv_close(client); + client = NULL; + } return 0; } -int recovery_send_devicetree(const char* ipsw, plist_t tss) { - irecv_client_t recovery = NULL; - const char* component = "devicetree"; - irecv_error_t recovery_error = IRECV_E_SUCCESS; +int recovery_send_devicetree(char* ipsw, plist_t tss) { + irecv_error_t error = 0; + irecv_client_t client = NULL; + char *component = "RestoreDeviceTree"; - if (recovery_open_with_timeout(&recovery) < 0) { + error = recovery_open_with_timeout(&client); + if (error != IRECV_E_SUCCESS) { return -1; } - if (recovery_send_signed_component(recovery, ipsw, tss, "RestoreDeviceTree") < 0) { + if (recovery_send_signed_component(client, ipsw, tss, component) < 0) { error("ERROR: Unable to send %s to device.\n", component); - irecv_close(recovery); + irecv_close(client); + client = NULL; return -1; } - recovery_error = irecv_send_command(recovery, "devicetree"); - if (recovery_error != IRECV_E_SUCCESS) { + error = irecv_send_command(client, "devicetree"); + if (error != IRECV_E_SUCCESS) { error("ERROR: Unable to execute %s\n", component); - irecv_close(recovery); + irecv_close(client); + client = NULL; return -1; } - irecv_close(recovery); - recovery = NULL; + if (client) { + irecv_close(client); + client = NULL; + } return 0; } -int recovery_send_ramdisk(const char* ipsw, plist_t tss) { - irecv_error_t recovery_error = IRECV_E_SUCCESS; - irecv_client_t recovery = NULL; - const char *component = "ramdisk"; +int recovery_send_ramdisk(char* ipsw, plist_t tss) { + irecv_error_t error = 0; + irecv_client_t client = NULL; + char *component = "RestoreRamDisk"; - recovery_error = recovery_open_with_timeout(&recovery); - if (recovery_error != IRECV_E_SUCCESS) { + error = recovery_open_with_timeout(&client); + if (error != IRECV_E_SUCCESS) { return -1; } - if (recovery_send_signed_component(recovery, ipsw, tss, "RestoreRamDisk") < 0) { + if (recovery_send_signed_component(client, ipsw, tss, component) < 0) { error("ERROR: Unable to send %s to device.\n", component); - irecv_close(recovery); + irecv_close(client); + client = NULL; return -1; } - recovery_error = irecv_send_command(recovery, "ramdisk"); - if (recovery_error != IRECV_E_SUCCESS) { + error = irecv_send_command(client, "ramdisk"); + if (error != IRECV_E_SUCCESS) { error("ERROR: Unable to execute %s\n", component); - irecv_close(recovery); + irecv_close(client); + client = NULL; return -1; } - irecv_close(recovery); - recovery = NULL; + if (client) { + irecv_close(client); + client = NULL; + } return 0; } -int recovery_send_kernelcache(const char* ipsw, plist_t tss) { - irecv_client_t recovery = NULL; - const char* component = "kernelcache"; - irecv_error_t recovery_error = IRECV_E_SUCCESS; +int recovery_send_kernelcache(char* ipsw, plist_t tss) { + irecv_error_t error = 0; + irecv_client_t client = NULL; + char *component = "RestoreKernelCache"; - if (recovery_open_with_timeout(&recovery) < 0) { + error = recovery_open_with_timeout(&client); + if (error != IRECV_E_SUCCESS) { return -1; } - if (recovery_send_signed_component(recovery, ipsw, tss, "RestoreKernelCache") < 0) { + if (recovery_send_signed_component(client, ipsw, tss, component) < 0) { error("ERROR: Unable to send %s to device.\n", component); - irecv_close(recovery); + irecv_close(client); + client = NULL; return -1; } - recovery_error = irecv_send_command(recovery, "bootx"); - if (recovery_error != IRECV_E_SUCCESS) { + error = irecv_send_command(client, "bootx"); + if (error != IRECV_E_SUCCESS) { error("ERROR: Unable to execute %s\n", component); - irecv_close(recovery); + irecv_close(client); + client = NULL; return -1; } - irecv_close(recovery); - recovery = NULL; - return 0; -} - -int recovery_get_ecid(uint64_t* ecid) { - irecv_client_t recovery = NULL; - irecv_error_t recovery_error = IRECV_E_SUCCESS; - - if (recovery_open_with_timeout(&recovery) < 0) { - return -1; - } - - recovery_error = irecv_get_ecid(recovery, ecid); - if (recovery_error != IRECV_E_SUCCESS) { - irecv_close(recovery); - return -1; - } - - irecv_close(recovery); - recovery = NULL; - return 0; -} - -int recovery_get_cpid(uint32_t* cpid) { - irecv_client_t recovery = NULL; - irecv_error_t recovery_error = IRECV_E_SUCCESS; - - if (recovery_open_with_timeout(&recovery) < 0) { - return -1; - } - - recovery_error = irecv_get_cpid(recovery, cpid); - if (recovery_error != IRECV_E_SUCCESS) { - irecv_close(recovery); - return -1; + if (client) { + irecv_close(client); + client = NULL; } - - irecv_close(recovery); - recovery = NULL; return 0; } -int recovery_get_bdid(uint32_t* bdid) { - irecv_client_t recovery = NULL; - irecv_error_t recovery_error = IRECV_E_SUCCESS; - - if (recovery_open_with_timeout(&recovery) < 0) { - return -1; - } - - recovery_error = irecv_get_bdid(recovery, bdid); - if (recovery_error != IRECV_E_SUCCESS) { - irecv_close(recovery); - return -1; - } - irecv_close(recovery); - recovery = NULL; +int recovery_get_ecid(uint64_t* ecid) { return 0; } |