From 4d74cd31751165b671eba9a1b0936718b7f39b52 Mon Sep 17 00:00:00 2001 From: Joshua Hill Date: Tue, 1 Jun 2010 16:13:25 -0400 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 26e7635460c7369be07455a7bcc7621cf53cdd2d Mon Sep 17 00:00:00 2001 From: Joshua Hill Date: Fri, 4 Jun 2010 16:02:05 -0400 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 0966c00988477450691c8c9bce47a3fb30eff6da Mon Sep 17 00:00:00 2001 From: Joshua Hill Date: Fri, 4 Jun 2010 23:17:05 -0400 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 255b285d22056dde283d33511c14387ea92e28c0 Mon Sep 17 00:00:00 2001 From: Joshua Hill Date: Sat, 5 Jun 2010 18:09:06 -0400 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 a91e336c24a0d741e47be7adf0cd0b2beb20e5ab Mon Sep 17 00:00:00 2001 From: Joshua Hill Date: Mon, 7 Jun 2010 02:24:08 -0400 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 04f32540c4e73c19281c2e7710b51d21ace6010b Mon Sep 17 00:00:00 2001 From: Joshua Hill Date: Tue, 8 Jun 2010 16:29:51 -0400 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 From 59fdd010aa845557b0eb90b98959c0cd112b638c Mon Sep 17 00:00:00 2001 From: Joshua Hill Date: Tue, 8 Jun 2010 20:34:28 -0400 Subject: started to add support multiple build identities --- src/recovery.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/recovery.c') diff --git a/src/recovery.c b/src/recovery.c index 361ce11..cc523f5 100644 --- a/src/recovery.c +++ b/src/recovery.c @@ -131,8 +131,8 @@ int recovery_send_signed_component(irecv_client_t client, const char* ipsw, plis free(data); return -1; } - free(data); + free(data); return 0; } -- cgit v1.1-32-gdbae From 2a2934ca1568dffe69da9a20420c7c0c71376bce Mon Sep 17 00:00:00 2001 From: Joshua Hill Date: Sun, 20 Jun 2010 22:12:31 -0400 Subject: fixed a few build errors within buildmanifest parsing --- src/recovery.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/recovery.c') diff --git a/src/recovery.c b/src/recovery.c index cc523f5..88d385f 100644 --- a/src/recovery.c +++ b/src/recovery.c @@ -158,7 +158,7 @@ int recovery_open_with_timeout(irecv_client_t* client) { } if (idevicerestore_debug) { - irecv_set_debug(recovery, idevicerestore_debug); + irecv_set_debug_level(idevicerestore_debug); } irecv_event_subscribe(recovery, IRECV_PROGRESS, &recovery_progress_callback, NULL); -- cgit v1.1-32-gdbae From 24afafe06f902bfd9f5652beb8797f24033c68bc Mon Sep 17 00:00:00 2001 From: Joshua Hill Date: Sun, 20 Jun 2010 22:02:18 -0400 Subject: Archived for historical reasons --- src/recovery.c | 47 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 39 insertions(+), 8 deletions(-) (limited to 'src/recovery.c') diff --git a/src/recovery.c b/src/recovery.c index 88d385f..bacfac7 100644 --- a/src/recovery.c +++ b/src/recovery.c @@ -28,16 +28,51 @@ #include "tss.h" #include "img3.h" +#include "common.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); + print_progress_bar(event->progress); } return 0; } +int recovery_client_new(struct idevicerestore_client_t* client) { + struct recovery_client_t* recovery = (struct recovery_client_t*) malloc(sizeof(struct recovery_client_t)); + if (recovery == NULL) { + error("ERROR: Out of memory\n"); + return -1; + } + + if (recovery_open_with_timeout(recovery) < 0) { + recovery_client_free(recovery); + return -1; + } + + if(recovery_check_mode(recovery) < 0) { + recovery_client_free(recovery); + return -1; + } + + client->recovery = recovery; + return 0; +} + +void recovery_client_free(struct idevicerestore_client_t* client) { + struct recovery_client_t* recovery = client->recovery; + if (recovery) { + if(recovery->client) { + irecv_close(recovery); + recovery = NULL; + } + free(recovery); + client->recovery = NULL; + + } +} + int recovery_check_mode() { irecv_client_t recovery = NULL; irecv_error_t recovery_error = IRECV_E_SUCCESS; @@ -101,11 +136,11 @@ int recovery_enter_restore(const char* uuid, const char* ipsw, plist_t tss) { } restore_close(device, restore); - idevicerestore_mode = MODE_RESTORE; + client->mode = &idevicerestore_modes[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(struct idevicerestore_client_t client, const char* ipsw, plist_t tss, char* component) { int size = 0; char* data = NULL; char* path = NULL; @@ -117,7 +152,7 @@ int recovery_send_signed_component(irecv_client_t client, const char* ipsw, plis return -1; } - if (get_signed_component(ipsw, tss, path, &data, &size) < 0) { + if (get_signed_component(client, ipsw, tss, path, &data, &size) < 0) { error("ERROR: Unable to get signed component: %s\n", component); free(path); return -1; @@ -157,10 +192,6 @@ int recovery_open_with_timeout(irecv_client_t* client) { debug("Retrying connection...\n"); } - if (idevicerestore_debug) { - irecv_set_debug_level(idevicerestore_debug); - } - irecv_event_subscribe(recovery, IRECV_PROGRESS, &recovery_progress_callback, NULL); *client = recovery; return 0; -- cgit v1.1-32-gdbae From 930f4b350474435e011b9dca18424dd1c42ea353 Mon Sep 17 00:00:00 2001 From: Joshua Hill Date: Mon, 21 Jun 2010 03:47:54 -0400 Subject: Finally fixed the out of control problem --- src/recovery.c | 197 ++++++++++++++++++++++----------------------------------- 1 file changed, 77 insertions(+), 120 deletions(-) (limited to 'src/recovery.c') diff --git a/src/recovery.c b/src/recovery.c index bacfac7..290f368 100644 --- a/src/recovery.c +++ b/src/recovery.c @@ -21,7 +21,6 @@ #include #include -#include #include #include #include @@ -29,6 +28,7 @@ #include "tss.h" #include "img3.h" #include "common.h" +#include "restore.h" #include "recovery.h" #include "idevicerestore.h" @@ -46,13 +46,8 @@ int recovery_client_new(struct idevicerestore_client_t* client) { return -1; } - if (recovery_open_with_timeout(recovery) < 0) { - recovery_client_free(recovery); - return -1; - } - - if(recovery_check_mode(recovery) < 0) { - recovery_client_free(recovery); + if (recovery_open_with_timeout(client) < 0) { + recovery_client_free(client); return -1; } @@ -61,16 +56,42 @@ int recovery_client_new(struct idevicerestore_client_t* client) { } void recovery_client_free(struct idevicerestore_client_t* client) { - struct recovery_client_t* recovery = client->recovery; - if (recovery) { - if(recovery->client) { - irecv_close(recovery); - recovery = NULL; + if(client) { + if (client->recovery) { + if(client->recovery->client) { + irecv_close(client->recovery->client); + client->recovery->client = NULL; + } + free(client->recovery); + client->recovery = NULL; + } + } +} + +int recovery_open_with_timeout(struct idevicerestore_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; } - free(recovery); - client->recovery = NULL; + if (i >= attempts) { + error("ERROR: Unable to connect to device in recovery mode\n"); + return -1; + } + + sleep(2); + debug("Retrying connection...\n"); } + + irecv_event_subscribe(recovery, IRECV_PROGRESS, &recovery_progress_callback, NULL); + client->recovery->client = recovery; + return 0; } int recovery_check_mode() { @@ -92,28 +113,28 @@ int recovery_check_mode() { return 0; } -int recovery_enter_restore(const char* uuid, const char* ipsw, plist_t tss) { +int recovery_enter_restore(struct idevicerestore_client_t* client) { idevice_t device = NULL; restored_client_t restore = NULL; // upload data to make device boot restore mode - if (recovery_send_ibec(ipsw, tss) < 0) { + if (recovery_send_ibec(client) < 0) { error("ERROR: Unable to send iBEC\n"); return -1; } sleep(1); - if (recovery_send_applelogo(ipsw, tss) < 0) { + if (recovery_send_applelogo(client) < 0) { error("ERROR: Unable to send AppleLogo\n"); return -1; } - if (recovery_send_devicetree(ipsw, tss) < 0) { + if (recovery_send_devicetree(client) < 0) { error("ERROR: Unable to send DeviceTree\n"); return -1; } - if (recovery_send_ramdisk(ipsw, tss) < 0) { + if (recovery_send_ramdisk(client) < 0) { error("ERROR: Unable to send Ramdisk\n"); return -1; } @@ -124,35 +145,35 @@ int recovery_enter_restore(const char* uuid, const char* ipsw, plist_t tss) { printf("Hit any key to continue..."); getchar(); - if (recovery_send_kernelcache(ipsw, tss) < 0) { + if (recovery_send_kernelcache(client) < 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) { + if (restore_open_with_timeout(client) < 0) { error("ERROR: Unable to connect to device in restore mode\n"); return -1; } - restore_close(device, restore); + restore_client_free(client); client->mode = &idevicerestore_modes[MODE_RESTORE]; return 0; } -int recovery_send_signed_component(struct idevicerestore_client_t client, const char* ipsw, plist_t tss, char* component) { +int recovery_send_signed_component(struct idevicerestore_client_t* client, const char* component) { int size = 0; char* data = NULL; char* path = NULL; char* blob = NULL; irecv_error_t error = 0; - if (tss_get_entry_path(tss, component, &path) < 0) { + if (tss_get_entry_path(client->tss, component, &path) < 0) { error("ERROR: Unable to get component path\n"); return -1; } - if (get_signed_component(client, ipsw, tss, path, &data, &size) < 0) { + if (get_signed_component(client, client->ipsw, client->tss, path, &data, &size) < 0) { error("ERROR: Unable to get signed component: %s\n", component); free(path); return -1; @@ -160,7 +181,7 @@ int recovery_send_signed_component(struct idevicerestore_client_t client, const free(path); info("Sending %s...\n", component); - error = irecv_send_buffer(client, data, size); + error = irecv_send_buffer(client->recovery->client, data, size); if (error != IRECV_E_SUCCESS) { error("ERROR: Unable to send component: %s\n", component); free(data); @@ -171,84 +192,47 @@ int recovery_send_signed_component(struct idevicerestore_client_t client, const return 0; } -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_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; - } - - sleep(2); - debug("Retrying connection...\n"); - } - - irecv_event_subscribe(recovery, IRECV_PROGRESS, &recovery_progress_callback, NULL); - *client = recovery; - return 0; -} - -int recovery_send_ibec(const char* ipsw, plist_t tss) { - irecv_client_t recovery = NULL; +int recovery_send_ibec(struct idevicerestore_client_t* client) { const char* component = "iBEC"; irecv_error_t recovery_error = IRECV_E_SUCCESS; - if (recovery_open_with_timeout(&recovery) < 0) { - return -1; - } - - recovery_error = irecv_send_command(recovery, "setenv auto-boot true"); + recovery_error = irecv_send_command(client->recovery->client, "setenv auto-boot true"); if (recovery_error != IRECV_E_SUCCESS) { error("ERROR: Unable to set auto-boot environmental variable\n"); - irecv_close(recovery); return -1; } - recovery_error = irecv_send_command(recovery, "saveenv"); + recovery_error = irecv_send_command(client->recovery->client, "saveenv"); if (recovery_error != IRECV_E_SUCCESS) { error("ERROR: Unable to save environmental variable\n"); - irecv_close(recovery); return -1; } - if (recovery_send_signed_component(recovery, ipsw, tss, "iBEC") < 0) { + if (recovery_send_signed_component(client, "iBEC") < 0) { error("ERROR: Unable to send %s to device.\n", component); - irecv_close(recovery); return -1; } - recovery_error = irecv_send_command(recovery, "go"); + recovery_error = irecv_send_command(client->recovery->client, "go"); if (recovery_error != IRECV_E_SUCCESS) { error("ERROR: Unable to execute %s\n", component); - irecv_close(recovery); return -1; } - irecv_close(recovery); - recovery = NULL; return 0; } -int recovery_send_applelogo(const char* ipsw, plist_t tss) { +int recovery_send_applelogo(struct idevicerestore_client_t* client) { irecv_client_t recovery = NULL; const char* component = "applelogo"; irecv_error_t recovery_error = IRECV_E_SUCCESS; info("Sending %s...\n", component); - if (recovery_open_with_timeout(&recovery) < 0) { + if (recovery_open_with_timeout(client) < 0) { return -1; } - if (recovery_send_signed_component(recovery, ipsw, tss, "AppleLogo") < 0) { + if (recovery_send_signed_component(client, "AppleLogo") < 0) { error("ERROR: Unable to send %s to device.\n", component); irecv_close(recovery); return -1; @@ -273,141 +257,114 @@ int recovery_send_applelogo(const char* ipsw, plist_t tss) { return 0; } -int recovery_send_devicetree(const char* ipsw, plist_t tss) { - irecv_client_t recovery = NULL; +int recovery_send_devicetree(struct idevicerestore_client_t* client) { const char* component = "devicetree"; irecv_error_t recovery_error = IRECV_E_SUCCESS; - if (recovery_open_with_timeout(&recovery) < 0) { + if (recovery_open_with_timeout(client) < 0) { return -1; } - if (recovery_send_signed_component(recovery, ipsw, tss, "RestoreDeviceTree") < 0) { + if (recovery_send_signed_component(client, "RestoreDeviceTree") < 0) { error("ERROR: Unable to send %s to device.\n", component); - irecv_close(recovery); return -1; } - recovery_error = irecv_send_command(recovery, "devicetree"); + recovery_error = irecv_send_command(client->recovery->client, "devicetree"); if (recovery_error != IRECV_E_SUCCESS) { error("ERROR: Unable to execute %s\n", component); - irecv_close(recovery); return -1; } - irecv_close(recovery); - recovery = NULL; return 0; } -int recovery_send_ramdisk(const char* ipsw, plist_t tss) { +int recovery_send_ramdisk(struct idevicerestore_client_t* client) { irecv_error_t recovery_error = IRECV_E_SUCCESS; - irecv_client_t recovery = NULL; const char *component = "ramdisk"; - recovery_error = recovery_open_with_timeout(&recovery); + recovery_error = recovery_open_with_timeout(client); if (recovery_error != IRECV_E_SUCCESS) { return -1; } - if (recovery_send_signed_component(recovery, ipsw, tss, "RestoreRamDisk") < 0) { + if (recovery_send_signed_component(client, "RestoreRamDisk") < 0) { error("ERROR: Unable to send %s to device.\n", component); - irecv_close(recovery); return -1; } - recovery_error = irecv_send_command(recovery, "ramdisk"); + recovery_error = irecv_send_command(client->recovery->client, "ramdisk"); if (recovery_error != IRECV_E_SUCCESS) { error("ERROR: Unable to execute %s\n", component); - irecv_close(recovery); return -1; } - irecv_close(recovery); - recovery = NULL; return 0; } -int recovery_send_kernelcache(const char* ipsw, plist_t tss) { - irecv_client_t recovery = NULL; +int recovery_send_kernelcache(struct idevicerestore_client_t* client) { const char* component = "kernelcache"; irecv_error_t recovery_error = IRECV_E_SUCCESS; - if (recovery_open_with_timeout(&recovery) < 0) { + if (recovery_open_with_timeout(client) < 0) { return -1; } - if (recovery_send_signed_component(recovery, ipsw, tss, "RestoreKernelCache") < 0) { + if (recovery_send_signed_component(client, "RestoreKernelCache") < 0) { error("ERROR: Unable to send %s to device.\n", component); - irecv_close(recovery); return -1; } - recovery_error = irecv_send_command(recovery, "bootx"); + recovery_error = irecv_send_command(client->recovery->client, "bootx"); if (recovery_error != IRECV_E_SUCCESS) { error("ERROR: Unable to execute %s\n", component); - irecv_close(recovery); return -1; } - irecv_close(recovery); - recovery = NULL; return 0; } -int recovery_get_ecid(uint64_t* ecid) { - irecv_client_t recovery = NULL; +int recovery_get_ecid(struct idevicerestore_client_t* client, uint64_t* ecid) { irecv_error_t recovery_error = IRECV_E_SUCCESS; - if (recovery_open_with_timeout(&recovery) < 0) { + if (recovery_open_with_timeout(client) < 0) { return -1; } - recovery_error = irecv_get_ecid(recovery, ecid); + recovery_error = irecv_get_ecid(client->recovery->client, 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; +int recovery_get_cpid(struct idevicerestore_client_t* client, uint32_t* cpid) { irecv_error_t recovery_error = IRECV_E_SUCCESS; - if (recovery_open_with_timeout(&recovery) < 0) { + if (recovery_open_with_timeout(client) < 0) { return -1; } - recovery_error = irecv_get_cpid(recovery, cpid); + recovery_error = irecv_get_cpid(client->recovery->client, cpid); if (recovery_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; +int recovery_get_bdid(struct idevicerestore_client_t* client, uint32_t* bdid) { irecv_error_t recovery_error = IRECV_E_SUCCESS; - if (recovery_open_with_timeout(&recovery) < 0) { + if (recovery_open_with_timeout(client) < 0) { return -1; } - recovery_error = irecv_get_bdid(recovery, bdid); + recovery_error = irecv_get_bdid(client->recovery->client, bdid); if (recovery_error != IRECV_E_SUCCESS) { - irecv_close(recovery); return -1; } - irecv_close(recovery); - recovery = NULL; return 0; } -- cgit v1.1-32-gdbae From 9ac5edef25cf7e084a639c2e70f9f7e963d96152 Mon Sep 17 00:00:00 2001 From: Joshua Hill Date: Tue, 22 Jun 2010 03:08:45 -0400 Subject: Added info for iPhone4 and fixed a few runtime errors --- src/recovery.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src/recovery.c') diff --git a/src/recovery.c b/src/recovery.c index 290f368..fbcc49c 100644 --- a/src/recovery.c +++ b/src/recovery.c @@ -45,6 +45,7 @@ int recovery_client_new(struct idevicerestore_client_t* client) { error("ERROR: Out of memory\n"); return -1; } + client->recovery = recovery; if (recovery_open_with_timeout(client) < 0) { recovery_client_free(client); @@ -74,6 +75,14 @@ int recovery_open_with_timeout(struct idevicerestore_client_t* client) { irecv_client_t recovery = NULL; irecv_error_t recovery_error = IRECV_E_UNKNOWN_ERROR; + if(client->recovery == NULL) { + if(recovery_client_new(client) < 0) { + error("ERROR: Unable to open device in recovery mode\n"); + return -1; + } + return 0; + } + for (i = 1; i <= attempts; i++) { recovery_error = irecv_open(&recovery); if (recovery_error == IRECV_E_SUCCESS) { -- cgit v1.1-32-gdbae From 628f5d0ee70daec242062a3dda3a7784d516dd30 Mon Sep 17 00:00:00 2001 From: Joshua Hill Date: Tue, 22 Jun 2010 03:35:54 -0400 Subject: Small change to make the program use irecovery command functions rather then duplicating them --- src/recovery.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/recovery.c') diff --git a/src/recovery.c b/src/recovery.c index fbcc49c..4240817 100644 --- a/src/recovery.c +++ b/src/recovery.c @@ -205,7 +205,8 @@ int recovery_send_ibec(struct idevicerestore_client_t* client) { const char* component = "iBEC"; irecv_error_t recovery_error = IRECV_E_SUCCESS; - recovery_error = irecv_send_command(client->recovery->client, "setenv auto-boot true"); + //recovery_error = irecv_send_command(client->recovery->client, "setenv auto-boot true"); + recovery_error = irecv_setenv(client->recovery->client, "auto-boot", "true"); if (recovery_error != IRECV_E_SUCCESS) { error("ERROR: Unable to set auto-boot environmental variable\n"); return -1; -- cgit v1.1-32-gdbae From a92e3de475368eea3c01372ce37d758a35e2a290 Mon Sep 17 00:00:00 2001 From: Martin Szulecki Date: Thu, 8 Jul 2010 19:12:56 +0200 Subject: Do not attempt to open another recovery session if one exists --- src/recovery.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'src/recovery.c') diff --git a/src/recovery.c b/src/recovery.c index 4240817..233224a 100644 --- a/src/recovery.c +++ b/src/recovery.c @@ -352,8 +352,10 @@ int recovery_get_ecid(struct idevicerestore_client_t* client, uint64_t* ecid) { int recovery_get_cpid(struct idevicerestore_client_t* client, uint32_t* cpid) { irecv_error_t recovery_error = IRECV_E_SUCCESS; - if (recovery_open_with_timeout(client) < 0) { - return -1; + if(client->recovery == NULL) { + if (recovery_open_with_timeout(client) < 0) { + return -1; + } } recovery_error = irecv_get_cpid(client->recovery->client, cpid); @@ -367,8 +369,10 @@ int recovery_get_cpid(struct idevicerestore_client_t* client, uint32_t* cpid) { int recovery_get_bdid(struct idevicerestore_client_t* client, uint32_t* bdid) { irecv_error_t recovery_error = IRECV_E_SUCCESS; - if (recovery_open_with_timeout(client) < 0) { - return -1; + if(client->recovery == NULL) { + if (recovery_open_with_timeout(client) < 0) { + return -1; + } } recovery_error = irecv_get_bdid(client->recovery->client, bdid); -- cgit v1.1-32-gdbae From 4090b98d9e8cdaada701ac320e20f7c8b0cf88f6 Mon Sep 17 00:00:00 2001 From: Martin Szulecki Date: Fri, 9 Jul 2010 03:47:42 +0200 Subject: Implement handling of devices which do not require a tss request This introduces passing around the "selected" build identity and fixes code logic issues to make idevicerestore work again. --- src/recovery.c | 121 ++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 73 insertions(+), 48 deletions(-) (limited to 'src/recovery.c') diff --git a/src/recovery.c b/src/recovery.c index 233224a..6a38343 100644 --- a/src/recovery.c +++ b/src/recovery.c @@ -45,6 +45,7 @@ int recovery_client_new(struct idevicerestore_client_t* client) { error("ERROR: Out of memory\n"); return -1; } + client->recovery = recovery; if (recovery_open_with_timeout(client) < 0) { @@ -122,28 +123,28 @@ int recovery_check_mode() { return 0; } -int recovery_enter_restore(struct idevicerestore_client_t* client) { +int recovery_enter_restore(struct idevicerestore_client_t* client, plist_t build_identity) { idevice_t device = NULL; restored_client_t restore = NULL; // upload data to make device boot restore mode - if (recovery_send_ibec(client) < 0) { + if (recovery_send_ibec(client, build_identity) < 0) { error("ERROR: Unable to send iBEC\n"); return -1; } - sleep(1); + sleep(2); - if (recovery_send_applelogo(client) < 0) { + if (recovery_send_applelogo(client, build_identity) < 0) { error("ERROR: Unable to send AppleLogo\n"); return -1; } - if (recovery_send_devicetree(client) < 0) { + if (recovery_send_devicetree(client, build_identity) < 0) { error("ERROR: Unable to send DeviceTree\n"); return -1; } - if (recovery_send_ramdisk(client) < 0) { + if (recovery_send_ramdisk(client, build_identity) < 0) { error("ERROR: Unable to send Ramdisk\n"); return -1; } @@ -154,7 +155,10 @@ int recovery_enter_restore(struct idevicerestore_client_t* client) { printf("Hit any key to continue..."); getchar(); - if (recovery_send_kernelcache(client) < 0) { + info("Resetting recovery mode connection...\n"); + irecv_reset(client->recovery->client); + + if (recovery_send_kernelcache(client, build_identity) < 0) { error("ERROR: Unable to send KernelCache\n"); return -1; } @@ -170,29 +174,42 @@ int recovery_enter_restore(struct idevicerestore_client_t* client) { return 0; } -int recovery_send_signed_component(struct idevicerestore_client_t* client, const char* component) { - int size = 0; +int recovery_send_component(struct idevicerestore_client_t* client, plist_t build_identity, const char* component) { + uint32_t size = 0; char* data = NULL; char* path = NULL; char* blob = NULL; irecv_error_t error = 0; - if (tss_get_entry_path(client->tss, component, &path) < 0) { - error("ERROR: Unable to get component path\n"); - return -1; + if (client->tss) { + if (tss_get_entry_path(client->tss, component, &path) < 0) { + error("ERROR: Unable to get component path\n"); + return -1; + } + } else { + if (build_identity_get_component_path(build_identity, component, &path) < 0) { + error("ERROR: Unable to get component: %s\n", component); + if (path) + free(path); + return -1; + } } - if (get_signed_component(client, client->ipsw, client->tss, path, &data, &size) < 0) { - error("ERROR: Unable to get signed component: %s\n", component); + info("Resetting recovery mode connection...\n"); + irecv_reset(client->recovery->client); + + if (ipsw_get_component_by_path(client->ipsw, client->tss, path, &data, &size) < 0) { + error("ERROR: Unable to get component: %s\n", component); free(path); return -1; } - free(path); - info("Sending %s...\n", component); + info("Sending %s (%d bytes)...\n", component, size); + error = irecv_send_buffer(client->recovery->client, data, size); + free(path); if (error != IRECV_E_SUCCESS) { - error("ERROR: Unable to send component: %s\n", component); + error("ERROR: Unable to send %s component: %s\n", component, irecv_strerror(error)); free(data); return -1; } @@ -201,10 +218,8 @@ int recovery_send_signed_component(struct idevicerestore_client_t* client, const return 0; } -int recovery_send_ibec(struct idevicerestore_client_t* client) { - const char* component = "iBEC"; +static int recovery_enable_autoboot(struct idevicerestore_client_t* client) { irecv_error_t recovery_error = IRECV_E_SUCCESS; - //recovery_error = irecv_send_command(client->recovery->client, "setenv auto-boot true"); recovery_error = irecv_setenv(client->recovery->client, "auto-boot", "true"); if (recovery_error != IRECV_E_SUCCESS) { @@ -218,7 +233,18 @@ int recovery_send_ibec(struct idevicerestore_client_t* client) { return -1; } - if (recovery_send_signed_component(client, "iBEC") < 0) { + return 0; +} + +int recovery_send_ibec(struct idevicerestore_client_t* client, plist_t build_identity) { + const char* component = "iBEC"; + irecv_error_t recovery_error = IRECV_E_SUCCESS; + + if (recovery_enable_autoboot(client) < 0) { + return -1; + } + + if (recovery_send_component(client, build_identity, component) < 0) { error("ERROR: Unable to send %s to device.\n", component); return -1; } @@ -232,9 +258,8 @@ int recovery_send_ibec(struct idevicerestore_client_t* client) { return 0; } -int recovery_send_applelogo(struct idevicerestore_client_t* client) { - irecv_client_t recovery = NULL; - const char* component = "applelogo"; +int recovery_send_applelogo(struct idevicerestore_client_t* client, plist_t build_identity) { + const char* component = "AppleLogo"; irecv_error_t recovery_error = IRECV_E_SUCCESS; info("Sending %s...\n", component); @@ -242,40 +267,37 @@ int recovery_send_applelogo(struct idevicerestore_client_t* client) { return -1; } - if (recovery_send_signed_component(client, "AppleLogo") < 0) { + if (recovery_send_component(client, build_identity, component) < 0) { error("ERROR: Unable to send %s to device.\n", component); - irecv_close(recovery); return -1; } - recovery_error = irecv_send_command(recovery, "setpicture 1"); + recovery_error = irecv_send_command(client->recovery->client, "setpicture 1"); if (recovery_error != IRECV_E_SUCCESS) { error("ERROR: Unable to set %s\n", component); - irecv_close(recovery); return -1; } - recovery_error = irecv_send_command(recovery, "bgcolor 0 0 0"); + recovery_error = irecv_send_command(client->recovery->client, "bgcolor 0 0 0"); if (recovery_error != IRECV_E_SUCCESS) { error("ERROR: Unable to display %s\n", component); - irecv_close(recovery); return -1; } - irecv_close(recovery); - recovery = NULL; return 0; } -int recovery_send_devicetree(struct idevicerestore_client_t* client) { - const char* component = "devicetree"; +int recovery_send_devicetree(struct idevicerestore_client_t* client, plist_t build_identity) { + const char* component = "RestoreDeviceTree"; irecv_error_t recovery_error = IRECV_E_SUCCESS; - if (recovery_open_with_timeout(client) < 0) { - return -1; + if(client->recovery == NULL) { + if (recovery_open_with_timeout(client) < 0) { + return -1; + } } - if (recovery_send_signed_component(client, "RestoreDeviceTree") < 0) { + if (recovery_send_component(client, build_identity, component) < 0) { error("ERROR: Unable to send %s to device.\n", component); return -1; } @@ -289,16 +311,17 @@ int recovery_send_devicetree(struct idevicerestore_client_t* client) { return 0; } -int recovery_send_ramdisk(struct idevicerestore_client_t* client) { +int recovery_send_ramdisk(struct idevicerestore_client_t* client, plist_t build_identity) { + const char *component = "RestoreRamDisk"; irecv_error_t recovery_error = IRECV_E_SUCCESS; - const char *component = "ramdisk"; - recovery_error = recovery_open_with_timeout(client); - if (recovery_error != IRECV_E_SUCCESS) { - return -1; + if(client->recovery == NULL) { + if (recovery_open_with_timeout(client) < 0) { + return -1; + } } - if (recovery_send_signed_component(client, "RestoreRamDisk") < 0) { + if (recovery_send_component(client, build_identity, component) < 0) { error("ERROR: Unable to send %s to device.\n", component); return -1; } @@ -312,15 +335,15 @@ int recovery_send_ramdisk(struct idevicerestore_client_t* client) { return 0; } -int recovery_send_kernelcache(struct idevicerestore_client_t* client) { - const char* component = "kernelcache"; +int recovery_send_kernelcache(struct idevicerestore_client_t* client, plist_t build_identity) { + const char* component = "RestoreKernelCache"; irecv_error_t recovery_error = IRECV_E_SUCCESS; if (recovery_open_with_timeout(client) < 0) { return -1; } - if (recovery_send_signed_component(client, "RestoreKernelCache") < 0) { + if (recovery_send_component(client, build_identity, component) < 0) { error("ERROR: Unable to send %s to device.\n", component); return -1; } @@ -337,8 +360,10 @@ int recovery_send_kernelcache(struct idevicerestore_client_t* client) { int recovery_get_ecid(struct idevicerestore_client_t* client, uint64_t* ecid) { irecv_error_t recovery_error = IRECV_E_SUCCESS; - if (recovery_open_with_timeout(client) < 0) { - return -1; + if(client->recovery == NULL) { + if (recovery_open_with_timeout(client) < 0) { + return -1; + } } recovery_error = irecv_get_ecid(client->recovery->client, ecid); -- cgit v1.1-32-gdbae