From bab56cf4083c2d0695215ba785019532ffae5749 Mon Sep 17 00:00:00 2001 From: Joshua Hill Date: Wed, 2 Jun 2010 04:13:25 +0800 Subject: Began major refactoring, not quite finished yet, this branch is probably broke --- src/recovery.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 72 insertions(+), 6 deletions(-) (limited to 'src/recovery.c') diff --git a/src/recovery.c b/src/recovery.c index 4e2e7ad..9885982 100644 --- a/src/recovery.c +++ b/src/recovery.c @@ -29,7 +29,26 @@ #include "recovery.h" #include "idevicerestore.h" -int recovery_send_signed_component(irecv_client_t client, char* ipsw, plist_t tss, char* component) { +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_send_signed_component(irecv_client_t client, const char* ipsw, plist_t tss, char* component) { int size = 0; char* data = NULL; char* path = NULL; @@ -77,7 +96,7 @@ irecv_error_t recovery_open_with_timeout(irecv_client_t* client) { return error; } -int recovery_send_ibec(char* ipsw, plist_t tss) { +int recovery_send_ibec(const char* ipsw, plist_t tss) { irecv_error_t error = 0; irecv_client_t client = NULL; char* component = "iBEC"; @@ -125,7 +144,7 @@ int recovery_send_ibec(char* ipsw, plist_t tss) { return 0; } -int recovery_send_applelogo(char* ipsw, plist_t tss) { +int recovery_send_applelogo(const char* ipsw, plist_t tss) { irecv_error_t error = 0; irecv_client_t client = NULL; char* component = "AppleLogo"; @@ -167,7 +186,7 @@ int recovery_send_applelogo(char* ipsw, plist_t tss) { return 0; } -int recovery_send_devicetree(char* ipsw, plist_t tss) { +int recovery_send_devicetree(const char* ipsw, plist_t tss) { irecv_error_t error = 0; irecv_client_t client = NULL; char *component = "RestoreDeviceTree"; @@ -199,7 +218,7 @@ int recovery_send_devicetree(char* ipsw, plist_t tss) { return 0; } -int recovery_send_ramdisk(char* ipsw, plist_t tss) { +int recovery_send_ramdisk(const char* ipsw, plist_t tss) { irecv_error_t error = 0; irecv_client_t client = NULL; char *component = "RestoreRamDisk"; @@ -231,7 +250,7 @@ int recovery_send_ramdisk(char* ipsw, plist_t tss) { return 0; } -int recovery_send_kernelcache(char* ipsw, plist_t tss) { +int recovery_send_kernelcache(const char* ipsw, plist_t tss) { irecv_error_t error = 0; irecv_client_t client = NULL; char *component = "RestoreKernelCache"; @@ -265,5 +284,52 @@ int recovery_send_kernelcache(char* ipsw, plist_t tss) { int recovery_get_ecid(uint64_t* ecid) { + irecv_client_t recovery = NULL; + if(recovery_open_with_timeout(&recovery) < 0) { + return -1; + } + + irecv_error_t error = irecv_get_ecid(recovery, ecid); + if (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; + if(recovery_open_with_timeout(&recovery) < 0) { + return -1; + } + + irecv_error_t error = irecv_get_ecid(recovery, cpid); + if (error != IRECV_E_SUCCESS) { + irecv_close(recovery); + return -1; + } + + irecv_close(recovery); + recovery = NULL; + return 0; +} + +int recovery_get_bdid(uint32_t* bdid) { + irecv_client_t recovery = NULL; + if(recovery_open_with_timeout(&recovery) < 0) { + return -1; + } + + irecv_error_t error = irecv_get_ecid(recovery, bdid); + if (error != IRECV_E_SUCCESS) { + irecv_close(recovery); + return -1; + } + + irecv_close(recovery); + recovery = NULL; return 0; } -- cgit v1.1-32-gdbae From ce999c67996515b278f49ea88f4e306dc0308ff3 Mon Sep 17 00:00:00 2001 From: Joshua Hill Date: Sat, 5 Jun 2010 04:02:05 +0800 Subject: Refactoring continued, lots of bug fixes, probably about half way through --- src/recovery.c | 41 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) (limited to 'src/recovery.c') diff --git a/src/recovery.c b/src/recovery.c index 9885982..3bfb97e 100644 --- a/src/recovery.c +++ b/src/recovery.c @@ -48,6 +48,43 @@ int recovery_check_mode() { return 0; } +int recovery_enter_restore(const char* ipsw, plist_t tss) { + // 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; + } + + return 0; +} + int recovery_send_signed_component(irecv_client_t client, const char* ipsw, plist_t tss, char* component) { int size = 0; char* data = NULL; @@ -306,7 +343,7 @@ int recovery_get_cpid(uint32_t* cpid) { return -1; } - irecv_error_t error = irecv_get_ecid(recovery, cpid); + irecv_error_t error = irecv_get_cpid(recovery, cpid); if (error != IRECV_E_SUCCESS) { irecv_close(recovery); return -1; @@ -323,7 +360,7 @@ int recovery_get_bdid(uint32_t* bdid) { return -1; } - irecv_error_t error = irecv_get_ecid(recovery, bdid); + irecv_error_t error = irecv_get_bdid(recovery, bdid); if (error != IRECV_E_SUCCESS) { irecv_close(recovery); return -1; -- cgit v1.1-32-gdbae From 7f98089a5e6663be50521063cf7171ab1bbc9fa2 Mon Sep 17 00:00:00 2001 From: Joshua Hill Date: Sat, 5 Jun 2010 11:17:05 +0800 Subject: Even more major cleanups and refactoring, this branch is still broken but starting to mature really well --- src/recovery.c | 247 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 122 insertions(+), 125 deletions(-) (limited to 'src/recovery.c') diff --git a/src/recovery.c b/src/recovery.c index 3bfb97e..a0a1151 100644 --- a/src/recovery.c +++ b/src/recovery.c @@ -23,6 +23,8 @@ #include #include #include +#include +#include #include "tss.h" #include "img3.h" @@ -38,7 +40,7 @@ int recovery_check_mode() { return -1; } - if(recovery->mode == kDfuMode) { + if (recovery->mode == kDfuMode) { irecv_close(recovery); return -1; } @@ -48,7 +50,10 @@ int recovery_check_mode() { return 0; } -int recovery_enter_restore(const char* ipsw, plist_t tss) { +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"); @@ -72,7 +77,7 @@ int recovery_enter_restore(const char* ipsw, plist_t tss) { } // for some reason iboot requires a hard reset after ramdisk - // or things start getting wacky + // or things start getting wacky printf("Please unplug your device, then plug it back in\n"); printf("Hit any key to continue..."); getchar(); @@ -82,6 +87,13 @@ int recovery_enter_restore(const char* ipsw, plist_t tss) { 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); + return 0; } @@ -90,244 +102,225 @@ int recovery_send_signed_component(irecv_client_t client, const char* ipsw, plis char* data = NULL; char* path = NULL; char* blob = NULL; - img3_file* img3 = NULL; irecv_error_t error = 0; - if (get_signed_component_by_name(ipsw, tss, component, &data, &size) < 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) { 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 IMG3: %s\n", path); - img3_free(img3); + error("ERROR: Unable to send component: %s\n", component); free(data); - free(path); return -1; } - - if (data) { - free(data); - data = NULL; - } + free(data); return 0; } -irecv_error_t recovery_open_with_timeout(irecv_client_t* client) { +int recovery_open_with_timeout(irecv_client_t* client) { int i = 0; - irecv_error_t error = 0; - for (i = 10; i > 0; i--) { - error = irecv_open(client); - if (error == IRECV_E_SUCCESS) { - return error; + int attempts = 10; + irecv_client_t recovery = NULL; + irecv_error_t recovery_error = IRECV_E_SUCCESS; + + for (i = 1; i <= attempts; i++) { + recovery_error = irecv_open(client); + if (recovery_error == IRECV_E_SUCCESS) { + break; + } + + if (i == attempts) { + error("ERROR: Unable to connect to device in recovery mode\n"); + return -1; } sleep(2); - info("Retrying connection...\n"); + debug("Retrying connection...\n"); } - error("ERROR: Unable to connect to recovery device.\n"); - return error; + *client = recovery; + return 0; } int recovery_send_ibec(const char* ipsw, plist_t tss) { - irecv_error_t error = 0; - irecv_client_t client = NULL; - char* component = "iBEC"; + irecv_client_t recovery = NULL; + const char* component = "iBEC"; + irecv_error_t recovery_error = IRECV_E_SUCCESS; - error = recovery_open_with_timeout(&client); - if (error != IRECV_E_SUCCESS) { + if (recovery_open_with_timeout(&recovery) < 0) { return -1; } - error = irecv_send_command(client, "setenv auto-boot true"); - if (error != IRECV_E_SUCCESS) { + recovery_error = irecv_send_command(recovery, "setenv auto-boot true"); + if (recovery_error != IRECV_E_SUCCESS) { error("ERROR: Unable to set auto-boot environmental variable\n"); - irecv_close(client); - client = NULL; + irecv_close(recovery); return -1; } - error = irecv_send_command(client, "saveenv"); - if (error != IRECV_E_SUCCESS) { + recovery_error = irecv_send_command(recovery, "saveenv"); + if (recovery_error != IRECV_E_SUCCESS) { error("ERROR: Unable to save environmental variable\n"); - irecv_close(client); - client = NULL; + irecv_close(recovery); return -1; } - if (recovery_send_signed_component(client, ipsw, tss, component) < 0) { + if (recovery_send_signed_component(recovery, ipsw, tss, "iBEC") < 0) { error("ERROR: Unable to send %s to device.\n", component); - irecv_close(client); - client = NULL; + irecv_close(recovery); return -1; } - error = irecv_send_command(client, "go"); - if (error != IRECV_E_SUCCESS) { + recovery_error = irecv_send_command(recovery, "go"); + if (recovery_error != IRECV_E_SUCCESS) { error("ERROR: Unable to execute %s\n", component); - irecv_close(client); - client = NULL; + irecv_close(recovery); return -1; } - if (client) { - irecv_close(client); - client = NULL; - } + irecv_close(recovery); + recovery = NULL; return 0; } int recovery_send_applelogo(const char* ipsw, plist_t tss) { - irecv_error_t error = 0; - irecv_client_t client = NULL; - char* component = "AppleLogo"; + irecv_client_t recovery = NULL; + const char* component = "applelogo"; + irecv_error_t recovery_error = IRECV_E_SUCCESS; info("Sending %s...\n", component); - - error = recovery_open_with_timeout(&client); - if (error != IRECV_E_SUCCESS) { + if (recovery_open_with_timeout(&recovery) < 0) { return -1; } - if (recovery_send_signed_component(client, ipsw, tss, component) < 0) { + if (recovery_send_signed_component(recovery, ipsw, tss, "AppleLogo") < 0) { error("ERROR: Unable to send %s to device.\n", component); - irecv_close(client); - client = NULL; + irecv_close(recovery); return -1; } - error = irecv_send_command(client, "setpicture 1"); - if (error != IRECV_E_SUCCESS) { + recovery_error = irecv_send_command(recovery, "setpicture 1"); + if (recovery_error != IRECV_E_SUCCESS) { error("ERROR: Unable to set %s\n", component); - irecv_close(client); - client = NULL; + irecv_close(recovery); return -1; } - error = irecv_send_command(client, "bgcolor 0 0 0"); - if (error != IRECV_E_SUCCESS) { + recovery_error = irecv_send_command(recovery, "bgcolor 0 0 0"); + if (recovery_error != IRECV_E_SUCCESS) { error("ERROR: Unable to display %s\n", component); - irecv_close(client); - client = NULL; + irecv_close(recovery); return -1; } - if (client) { - irecv_close(client); - client = NULL; - } + irecv_close(recovery); + recovery = NULL; return 0; } int recovery_send_devicetree(const char* ipsw, plist_t tss) { - irecv_error_t error = 0; - irecv_client_t client = NULL; - char *component = "RestoreDeviceTree"; + irecv_client_t recovery = NULL; + const char* component = "devicetree"; + irecv_error_t recovery_error = IRECV_E_SUCCESS; - error = recovery_open_with_timeout(&client); - if (error != IRECV_E_SUCCESS) { + if (recovery_open_with_timeout(&recovery) < 0) { return -1; } - if (recovery_send_signed_component(client, ipsw, tss, component) < 0) { + if (recovery_send_signed_component(recovery, ipsw, tss, "RestoreDeviceTree") < 0) { error("ERROR: Unable to send %s to device.\n", component); - irecv_close(client); - client = NULL; + irecv_close(recovery); return -1; } - error = irecv_send_command(client, "devicetree"); - if (error != IRECV_E_SUCCESS) { + recovery_error = irecv_send_command(recovery, "devicetree"); + if (recovery_error != IRECV_E_SUCCESS) { error("ERROR: Unable to execute %s\n", component); - irecv_close(client); - client = NULL; + irecv_close(recovery); return -1; } - if (client) { - irecv_close(client); - client = NULL; - } + irecv_close(recovery); + recovery = NULL; return 0; } int recovery_send_ramdisk(const char* ipsw, plist_t tss) { - irecv_error_t error = 0; - irecv_client_t client = NULL; - char *component = "RestoreRamDisk"; + irecv_error_t recovery_error = IRECV_E_SUCCESS; + irecv_client_t recovery = NULL; + const char *component = "ramdisk"; - error = recovery_open_with_timeout(&client); - if (error != IRECV_E_SUCCESS) { + recovery_error = recovery_open_with_timeout(&recovery); + if (recovery_error != IRECV_E_SUCCESS) { return -1; } - if (recovery_send_signed_component(client, ipsw, tss, component) < 0) { + if (recovery_send_signed_component(recovery, ipsw, tss, "RestoreRamDisk") < 0) { error("ERROR: Unable to send %s to device.\n", component); - irecv_close(client); - client = NULL; + irecv_close(recovery); return -1; } - error = irecv_send_command(client, "ramdisk"); - if (error != IRECV_E_SUCCESS) { + recovery_error = irecv_send_command(recovery, "ramdisk"); + if (recovery_error != IRECV_E_SUCCESS) { error("ERROR: Unable to execute %s\n", component); - irecv_close(client); - client = NULL; + irecv_close(recovery); return -1; } - if (client) { - irecv_close(client); - client = NULL; - } + irecv_close(recovery); + recovery = NULL; return 0; } int recovery_send_kernelcache(const char* ipsw, plist_t tss) { - irecv_error_t error = 0; - irecv_client_t client = NULL; - char *component = "RestoreKernelCache"; + irecv_client_t recovery = NULL; + const char* component = "kernelcache"; + irecv_error_t recovery_error = IRECV_E_SUCCESS; - error = recovery_open_with_timeout(&client); - if (error != IRECV_E_SUCCESS) { + if (recovery_open_with_timeout(&recovery) < 0) { return -1; } - if (recovery_send_signed_component(client, ipsw, tss, component) < 0) { + if (recovery_send_signed_component(recovery, ipsw, tss, "RestoreKernelCache") < 0) { error("ERROR: Unable to send %s to device.\n", component); - irecv_close(client); - client = NULL; + irecv_close(recovery); return -1; } - error = irecv_send_command(client, "bootx"); - if (error != IRECV_E_SUCCESS) { + recovery_error = irecv_send_command(recovery, "bootx"); + if (recovery_error != IRECV_E_SUCCESS) { error("ERROR: Unable to execute %s\n", component); - irecv_close(client); - client = NULL; + irecv_close(recovery); return -1; } - if (client) { - irecv_close(client); - client = NULL; - } + irecv_close(recovery); + recovery = NULL; return 0; } - int recovery_get_ecid(uint64_t* ecid) { irecv_client_t recovery = NULL; - if(recovery_open_with_timeout(&recovery) < 0) { + irecv_error_t recovery_error = IRECV_E_SUCCESS; + + if (recovery_open_with_timeout(&recovery) < 0) { return -1; } - irecv_error_t error = irecv_get_ecid(recovery, ecid); - if (error != IRECV_E_SUCCESS) { + recovery_error = irecv_get_ecid(recovery, ecid); + if (recovery_error != IRECV_E_SUCCESS) { irecv_close(recovery); return -1; } @@ -339,12 +332,14 @@ int recovery_get_ecid(uint64_t* ecid) { int recovery_get_cpid(uint32_t* cpid) { irecv_client_t recovery = NULL; - if(recovery_open_with_timeout(&recovery) < 0) { + irecv_error_t recovery_error = IRECV_E_SUCCESS; + + if (recovery_open_with_timeout(&recovery) < 0) { return -1; } - irecv_error_t error = irecv_get_cpid(recovery, cpid); - if (error != IRECV_E_SUCCESS) { + recovery_error = irecv_get_cpid(recovery, cpid); + if (recovery_error != IRECV_E_SUCCESS) { irecv_close(recovery); return -1; } @@ -356,12 +351,14 @@ int recovery_get_cpid(uint32_t* cpid) { int recovery_get_bdid(uint32_t* bdid) { irecv_client_t recovery = NULL; - if(recovery_open_with_timeout(&recovery) < 0) { + irecv_error_t recovery_error = IRECV_E_SUCCESS; + + if (recovery_open_with_timeout(&recovery) < 0) { return -1; } - irecv_error_t error = irecv_get_bdid(recovery, bdid); - if (error != IRECV_E_SUCCESS) { + recovery_error = irecv_get_bdid(recovery, bdid); + if (recovery_error != IRECV_E_SUCCESS) { irecv_close(recovery); return -1; } -- cgit v1.1-32-gdbae From 9279f889d7e296880fd7ea9d6c7cec499db62ea4 Mon Sep 17 00:00:00 2001 From: Joshua Hill Date: Sun, 6 Jun 2010 06:09:06 +0800 Subject: Changed the device type to a structure array for cleaner code and cross state access --- src/recovery.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/recovery.c') diff --git a/src/recovery.c b/src/recovery.c index a0a1151..e67b10d 100644 --- a/src/recovery.c +++ b/src/recovery.c @@ -132,15 +132,15 @@ int 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_SUCCESS; + irecv_error_t recovery_error = IRECV_E_UNKNOWN_ERROR; for (i = 1; i <= attempts; i++) { - recovery_error = irecv_open(client); + recovery_error = irecv_open(&recovery); if (recovery_error == IRECV_E_SUCCESS) { break; } - if (i == attempts) { + if (i >= attempts) { error("ERROR: Unable to connect to device in recovery mode\n"); return -1; } -- cgit v1.1-32-gdbae From a274554b753880dd7042b6013d0158a0b81124c7 Mon Sep 17 00:00:00 2001 From: Joshua Hill Date: Mon, 7 Jun 2010 14:24:08 +0800 Subject: I really need to put more descriptive messages here, but im doing stuff all over the place --- src/recovery.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'src/recovery.c') diff --git a/src/recovery.c b/src/recovery.c index e67b10d..52f4802 100644 --- a/src/recovery.c +++ b/src/recovery.c @@ -31,6 +31,13 @@ #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; @@ -92,8 +99,9 @@ int recovery_enter_restore(const char* uuid, const char* ipsw, plist_t tss) { error("ERROR: Unable to connect to device in restore mode\n"); return -1; } - restore_close(device, restore); + restore_close(device, restore); + idevicerestore_mode = MODE_RESTORE; return 0; } @@ -149,6 +157,7 @@ int recovery_open_with_timeout(irecv_client_t* client) { debug("Retrying connection...\n"); } + irecv_event_subscribe(recovery, IRECV_PROGRESS, &recovery_progress_callback, NULL); *client = recovery; return 0; } -- cgit v1.1-32-gdbae From bd7a45ad71862da6ecd96a1156bf5b1e123e3c43 Mon Sep 17 00:00:00 2001 From: Joshua Hill Date: Wed, 9 Jun 2010 04:29:51 +0800 Subject: Added debug info for recovery.c and a few minor fixes to asr.c --- src/recovery.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/recovery.c') diff --git a/src/recovery.c b/src/recovery.c index 52f4802..361ce11 100644 --- a/src/recovery.c +++ b/src/recovery.c @@ -157,6 +157,10 @@ int recovery_open_with_timeout(irecv_client_t* client) { debug("Retrying connection...\n"); } + if (idevicerestore_debug) { + irecv_set_debug(recovery, idevicerestore_debug); + } + irecv_event_subscribe(recovery, IRECV_PROGRESS, &recovery_progress_callback, NULL); *client = recovery; return 0; -- cgit v1.1-32-gdbae