From 6085ed7429986c7dec579fe1f1303ae6651ea1f2 Mon Sep 17 00:00:00 2001 From: Nikias Bassen Date: Thu, 9 Nov 2023 01:56:08 +0100 Subject: Print progress for large components (e.g. Cryptex) --- src/common.c | 2 +- src/idevicerestore.h | 1 + src/ipsw.c | 8 ++++---- src/ipsw.h | 2 +- src/restore.c | 41 ++++++++++++++++++++++++++++++++++------- 5 files changed, 41 insertions(+), 13 deletions(-) diff --git a/src/common.c b/src/common.c index 0ad775c..bb534e2 100644 --- a/src/common.c +++ b/src/common.c @@ -467,7 +467,7 @@ void idevicerestore_progress(struct idevicerestore_client_t* client, int step, d client->progress_cb(step, progress, client->progress_cb_data); } else { // we don't want to be too verbose in regular idevicerestore. - if ((step == RESTORE_STEP_UPLOAD_FS) || (step == RESTORE_STEP_VERIFY_FS) || (step == RESTORE_STEP_FLASH_FW)) { + if ((step == RESTORE_STEP_UPLOAD_FS) || (step == RESTORE_STEP_VERIFY_FS) || (step == RESTORE_STEP_FLASH_FW) || (step == RESTORE_STEP_UPLOAD_IMG)) { print_progress_bar(100.0 * progress); } } diff --git a/src/idevicerestore.h b/src/idevicerestore.h index 880562f..e1a767c 100644 --- a/src/idevicerestore.h +++ b/src/idevicerestore.h @@ -63,6 +63,7 @@ enum { RESTORE_STEP_FLASH_FW, RESTORE_STEP_FLASH_BB, RESTORE_STEP_FUD, + RESTORE_STEP_UPLOAD_IMG, RESTORE_NUM_STEPS }; diff --git a/src/ipsw.c b/src/ipsw.c index 5b1d732..c25f61d 100644 --- a/src/ipsw.c +++ b/src/ipsw.c @@ -737,7 +737,7 @@ int ipsw_extract_send(ipsw_archive_t ipsw, const char* infile, int blocksize, ip // EOF break; } - if (send_callback(ctx, buffer, zr) < 0) { + if (send_callback(ctx, buffer, zr, done, total_size) < 0) { error("ERROR: %s: send failed\n", __func__); break; } @@ -773,7 +773,7 @@ int ipsw_extract_send(ipsw_archive_t ipsw, const char* infile, int blocksize, ip free(buffer); return -1; } - send_callback(ctx, buffer, (size_t)rl); + send_callback(ctx, buffer, (size_t)rl, 0, 0); } else { #endif FILE *f = fopen(filepath, "rb"); @@ -792,7 +792,7 @@ int ipsw_extract_send(ipsw_archive_t ipsw, const char* infile, int blocksize, ip error("ERROR: %s: fread failed for %s: %s\n", __func__, filepath, strerror(errno)); break; } - if (send_callback(ctx, buffer, fr) < 0) { + if (send_callback(ctx, buffer, fr, done, total_size) < 0) { error("ERROR: %s: send failed\n", __func__); break; } @@ -812,7 +812,7 @@ int ipsw_extract_send(ipsw_archive_t ipsw, const char* infile, int blocksize, ip } // send a NULL buffer to mark end of transfer - send_callback(ctx, NULL, 0); + send_callback(ctx, NULL, 0, done, total_size); return 0; } diff --git a/src/ipsw.h b/src/ipsw.h index 56faf94..f0e11a1 100644 --- a/src/ipsw.h +++ b/src/ipsw.h @@ -44,7 +44,7 @@ void ipsw_close(ipsw_archive_t ipsw); int ipsw_print_info(const char* ipsw); typedef int (*ipsw_list_cb)(void *ctx, ipsw_archive_t ipsw, const char *name, struct stat *stat); -typedef int (*ipsw_send_cb)(void *ctx, void *data, size_t size); +typedef int (*ipsw_send_cb)(void *ctx, void *data, size_t size, size_t done, size_t total_size); struct ipsw_file_handle { FILE* file; diff --git a/src/restore.c b/src/restore.c index 9e0268a..7727411 100644 --- a/src/restore.c +++ b/src/restore.c @@ -3537,7 +3537,13 @@ int extract_global_manifest(struct idevicerestore_client_t* client, plist_t buil return 0; } -static int _restore_send_file_data(restored_client_t restore, void* data, size_t size) +struct _restore_send_file_data_ctx { + struct idevicerestore_client_t* client; + restored_client_t restore; + int last_progress; +}; + +static int _restore_send_file_data(struct _restore_send_file_data_ctx* rctx, void* data, size_t size, size_t done, size_t total_size) { plist_t dict = plist_new_dict(); if (data != NULL) { @@ -3547,13 +3553,21 @@ static int _restore_send_file_data(restored_client_t restore, void* data, size_t // Send FileDataDone to mark end of transfer plist_dict_set_item(dict, "FileDataDone", plist_new_bool(1)); } - restored_error_t restore_error = restored_send(restore, dict); + restored_error_t restore_error = restored_send(rctx->restore, dict); if (restore_error != RESTORE_E_SUCCESS) { plist_free(dict); error("ERROR: %s: Failed to send data (%d)\n", __func__, restore_error); return -1; } plist_free(dict); + if (total_size > 0) { + double progress = (double)done / (double)total_size; + int progress_int = (int)(progress*100.0); + if (progress_int > rctx->last_progress) { + idevicerestore_progress(rctx->client, RESTORE_STEP_UPLOAD_IMG, progress); + rctx->last_progress = progress_int; + } + } return 0; } @@ -3643,12 +3657,17 @@ int restore_send_personalized_boot_object_v3(restored_client_t restore, struct i } } - info("Sending %s now...\n", component); + info("Sending %s now (%" PRIu64 " bytes)...\n", component, (uint64_t)size); + + struct _restore_send_file_data_ctx rctx; + rctx.client = client; + rctx.restore = restore; + rctx.last_progress = 0; int64_t i = size; while (i > 0) { int blob_size = i > 8192 ? 8192 : i; - if (_restore_send_file_data(restore, (data + size - i), blob_size) < 0) { + if (_restore_send_file_data(&rctx, (data + size - i), blob_size, size-i, size) < 0) { free(data); error("ERROR: Unable to send component %s data\n", component); return -1; @@ -3657,7 +3676,7 @@ int restore_send_personalized_boot_object_v3(restored_client_t restore, struct i } free(data); - _restore_send_file_data(restore, NULL, 0); + _restore_send_file_data(&rctx, NULL, 0, size-i, size); info("Done sending %s\n", component); return 0; @@ -3733,9 +3752,17 @@ int restore_send_source_boot_object_v4(restored_client_t restore, struct idevice return -1; } - info("Sending %s now...\n", component); + uint64_t fsize = 0; + ipsw_get_file_size(client->ipsw, path, &fsize); + + info("Sending %s now (%" PRIu64 " bytes)\n", component, fsize); + + struct _restore_send_file_data_ctx rctx; + rctx.client = client; + rctx.restore = restore; + rctx.last_progress = 0; - if (ipsw_extract_send(client->ipsw, path, 8192, (ipsw_send_cb)_restore_send_file_data, restore) < 0) { + if (ipsw_extract_send(client->ipsw, path, 8192, (ipsw_send_cb)_restore_send_file_data, &rctx) < 0) { free(path); error("ERROR: Failed to send component %s\n", component); return -1; -- cgit v1.1-32-gdbae