diff options
author | 2015-10-09 03:07:34 +0200 | |
---|---|---|
committer | 2015-10-09 03:07:34 +0200 | |
commit | 7336b600a160d731231d3ab05506e7be0c05f4e0 (patch) | |
tree | 0d6f362a80b4f1c33f97f278be925ab655bb7155 /src/idevicerestore.c | |
parent | 46ead9b3afd6e79fa05a391b94bc929e94101e33 (diff) | |
download | idevicerestore-7336b600a160d731231d3ab05506e7be0c05f4e0.tar.gz idevicerestore-7336b600a160d731231d3ab05506e7be0c05f4e0.tar.bz2 |
Select build identity based on hardware model instead of first or last identity in manifest
While this might have worked in the past it didn't work anymore with the
iPhone 6S (plus) since it comes with two different CPUs (Samsung & TSMC A9).
Therefore the BuildManifest.plist has multiple build identities and for a
successful restore the correct build identity has to be selected for the
actual hardware model of the corresponding device.
Diffstat (limited to 'src/idevicerestore.c')
-rw-r--r-- | src/idevicerestore.c | 70 |
1 files changed, 61 insertions, 9 deletions
diff --git a/src/idevicerestore.c b/src/idevicerestore.c index f02e7b0..ed1f53f 100644 --- a/src/idevicerestore.c +++ b/src/idevicerestore.c @@ -540,21 +540,16 @@ int idevicerestore_start(struct idevicerestore_client_t* client) plist_dict_set_item(build_identity, "Manifest", manifest); } } else if (client->flags & FLAG_ERASE) { - build_identity = build_manifest_get_build_identity(buildmanifest, 0); + build_identity = build_manifest_get_build_identity_for_model_with_restore_behavior(buildmanifest, client->device->hardware_model, "Erase"); if (build_identity == NULL) { error("ERROR: Unable to find any build identities\n"); plist_free(buildmanifest); return -1; } } else { - // loop through all build identities in the build manifest - // and list the valid ones - int i = 0; - int valid_builds = 0; - int build_count = build_manifest_get_identity_count(buildmanifest); - for (i = 0; i < build_count; i++) { - build_identity = build_manifest_get_build_identity(buildmanifest, i); - valid_builds++; + build_identity = build_manifest_get_build_identity_for_model_with_restore_behavior(buildmanifest, client->device->hardware_model, "Update"); + if (!build_identity) { + build_identity = build_manifest_get_build_identity_for_model(buildmanifest, client->device->hardware_model); } } @@ -1366,6 +1361,63 @@ plist_t build_manifest_get_build_identity(plist_t build_manifest, uint32_t ident return plist_copy(build_identity); } +plist_t build_manifest_get_build_identity_for_model_with_restore_behavior(plist_t build_manifest, const char *hardware_model, const char *behavior) +{ + plist_t build_identities_array = plist_dict_get_item(build_manifest, "BuildIdentities"); + if (!build_identities_array || plist_get_node_type(build_identities_array) != PLIST_ARRAY) { + error("ERROR: Unable to find build identities node\n"); + return NULL; + } + + uint32_t i; + for (i = 0; i < plist_array_get_size(build_identities_array); i++) { + plist_t ident = plist_array_get_item(build_identities_array, i); + if (!ident || plist_get_node_type(ident) != PLIST_DICT) { + continue; + } + plist_t info_dict = plist_dict_get_item(ident, "Info"); + if (!info_dict || plist_get_node_type(ident) != PLIST_DICT) { + continue; + } + plist_t devclass = plist_dict_get_item(info_dict, "DeviceClass"); + if (!devclass || plist_get_node_type(devclass) != PLIST_STRING) { + continue; + } + char *str = NULL; + plist_get_string_val(devclass, &str); + if (strcasecmp(str, hardware_model) != 0) { + free(str); + continue; + } + free(str); + str = NULL; + if (behavior) { + plist_t rbehavior = plist_dict_get_item(info_dict, "RestoreBehavior"); + if (!rbehavior || plist_get_node_type(rbehavior) != PLIST_STRING) { + continue; + } + plist_get_string_val(rbehavior, &str); + if (strcasecmp(str, behavior) != 0) { + free(str); + continue; + } else { + free(str); + return plist_copy(ident); + } + free(str); + } else { + return plist_copy(ident); + } + } + + return NULL; +} + +plist_t build_manifest_get_build_identity_for_model(plist_t build_manifest, const char *hardware_model) +{ + return build_manifest_get_build_identity_for_model_with_restore_behavior(build_manifest, hardware_model, NULL); +} + int get_tss_response(struct idevicerestore_client_t* client, plist_t build_identity, plist_t* tss) { plist_t request = NULL; plist_t response = NULL; |