int nandroid_restore_partition(const char* backup_path, const char* root) { Volume *vol = volume_for_path(root); // make sure the volume exists... if (vol == NULL || vol->fs_type == NULL) return 0; // see if we need a raw restore (mtd) char tmp[PATH_MAX]; if (strcmp(vol->fs_type, "mtd") == 0 || strcmp(vol->fs_type, "bml") == 0 || strcmp(vol->fs_type, "emmc") == 0) { int ret; const char* name = basename(root); ui_print("恢复之前先清除 %s \n", name); if (0 != (ret = format_volume(root))) { ui_print("清除 %s 镜像失败...", name); return ret; } if (strcmp(backup_path, "-") == 0) strcpy(tmp, backup_path); else sprintf(tmp, "%s%s.img", backup_path, root); ui_print("正在恢复 %s 镜像...\n", name); if (0 != (ret = restore_raw_partition(vol->fs_type, vol->device, tmp))) { ui_print("刷写 %s 镜像失败!", name); return ret; } return 0; } return nandroid_restore_partition_extended(backup_path, root, 1); }
int nandroid_restore_partition(const char* backup_path, const char* root) { Volume *vol = volume_for_path(root); // make sure the volume exists... if (vol == NULL || vol->fs_type == NULL) return 0; // see if we need a raw restore (mtd) char tmp[PATH_MAX]; if (strcmp(vol->fs_type, "mtd") == 0 || strcmp(vol->fs_type, "bml") == 0 || strcmp(vol->fs_type, "emmc") == 0) { int ret; const char* name = basename(root); ui_print("Erasing %s before restore...\n", name); if (0 != (ret = format_volume(root))) { ui_print("Error while erasing %s image!", name); return ret; } sprintf(tmp, "%s%s.img", backup_path, root); ui_print("Restoring %s image...\n", name); if (0 != (ret = restore_raw_partition(vol->fs_type, vol->device, tmp))) { ui_print("Error while flashing %s image!", name); return ret; } return 0; } return nandroid_restore_partition_extended(backup_path, root, 1); }
int nandroid_restore(const char* backup_path, int restore_boot, int restore_system, int restore_data, int restore_cache, int restore_sdext) { ui_set_background(BACKGROUND_ICON_INSTALLING); ui_show_indeterminate_progress(); yaffs_files_total = 0; if (ensure_root_path_mounted("SDCARD:") != 0) return print_and_error("Can't mount /sdcard\n"); char tmp[PATH_MAX]; //ui_print("Checking MD5 sums...\n"); //sprintf(tmp, "cd %s && md5sum -c nandroid.md5", backup_path); //if (0 != __system(tmp)) // return print_and_error("MD5 mismatch!\n"); int ret; #ifndef BOARD_RECOVERY_IGNORE_BOOTABLES if (restore_boot) { ui_print("Erasing boot before restore...\n"); if (0 != (ret = format_root_device("BOOT:"))) return print_and_error("Error while formatting BOOT:!\n"); sprintf(tmp, "%s/boot.img", backup_path); ui_print("Restoring boot image...\n"); if (0 != (ret = restore_raw_partition("boot", tmp))) { ui_print("Error while flashing boot image!"); return ret; } } #endif if (restore_system && 0 != (ret = nandroid_restore_partition(backup_path, "SYSTEM:"))) return ret; if (restore_data && 0 != (ret = nandroid_restore_partition(backup_path, "DATA:"))) return ret; #ifdef BOARD_HAS_DATADATA if (restore_data && 0 != (ret = nandroid_restore_partition(backup_path, "DATADATA:"))) return ret; #endif if (restore_data && 0 != (ret = nandroid_restore_partition_extended(backup_path, "SDCARD:/.android_secure", 0))) return ret; if (restore_cache && 0 != (ret = nandroid_restore_partition_extended(backup_path, "CACHE:", 0))) return ret; if (restore_sdext && 0 != (ret = nandroid_restore_partition(backup_path, "SDEXT:"))) return ret; sync(); ui_set_background(BACKGROUND_ICON_NONE); ui_reset_progress(); ui_print("\nRestore complete!\n"); return 0; }
int main(int argc, char **argv) { if (argc != 3) { fprintf(stderr, "usage: %s partition file.img\n", argv[0]); return 2; } int ret = restore_raw_partition(NULL, argv[1], argv[2]); if (ret != 0) fprintf(stderr, "failed with error: %d\n", ret); return ret; }
int nandroid_restore_partition(const char* backup_path, const char* root) { Volume *vol = volume_for_path(root); // make sure the volume exists... if (vol == NULL || vol->fs_type == NULL) { ui_print("Volume not found! Skipping restore of %s...\n", root); return 0; } // see if we need a raw restore (mtd) char tmp[PATH_MAX]; if (strcmp(vol->fs_type, "mtd") == 0 || strcmp(vol->fs_type, "bml") == 0 || strcmp(vol->fs_type, "emmc") == 0) { int ret; const char* name = basename(root); //fix partition could be formatted when no image to restore (exp: if md5 check disabled and empty backup folder) struct stat file_check; sprintf(tmp, "%s%s.img", backup_path, root); if (0 != stat(tmp, &file_check)) { ui_print("%s.img not found. Skipping restore of %s\n", name, root); return 0; } ui_print("Erasing %s before restore...\n", name); if (0 != (ret = format_volume(root))) { ui_print("Error while erasing %s image!\n", name); return ret; } //sprintf(tmp, "%s%s.img", backup_path, root); ui_print("Restoring %s image...\n", name); if (0 != (ret = restore_raw_partition(vol->fs_type, vol->device, tmp))) { ui_print("Error while flashing %s image!\n", name); return ret; } return 0; } return nandroid_restore_partition_extended(backup_path, root, 1); }
// write_raw_image(filename_or_blob, partition) Value* WriteRawImageFn(const char* name, State* state, int argc, Expr* argv[]) { char* result = NULL; Value* partition_value; Value* contents; if (ReadValueArgs(state, argv, 2, &contents, &partition_value) < 0) { return NULL; } char* partition = NULL; if (partition_value->type != VAL_STRING) { ErrorAbort(state, "partition argument to %s must be string", name); goto done; } partition = partition_value->data; if (strlen(partition) == 0) { ErrorAbort(state, "partition argument to %s can't be empty", name); goto done; } if (contents->type == VAL_STRING && strlen((char*) contents->data) == 0) { ErrorAbort(state, "file argument to %s can't be empty", name); goto done; } char* filename = contents->data; if (0 == restore_raw_partition(NULL, partition, filename)) result = strdup(partition); else { result = strdup(""); goto done; } done: if (result != partition) FreeValue(partition_value); FreeValue(contents); return StringValue(result); }
int nandroid_restore(const char* backup_path, int restore_boot, int restore_system, int restore_data, int restore_cache, int restore_sdext, int restore_wimax) { ui_set_background(BACKGROUND_ICON_INSTALLING); ui_show_indeterminate_progress(); if (ensure_path_mounted(backup_path) != 0) return print_and_error("Can't mount backup path\n"); char tmp[PATH_MAX]; #ifdef PHILZ_TOUCH_RECOVERY if (enable_md5sum) #endif { ui_print("Checking MD5 sums...\n"); sprintf(tmp, "cd %s && md5sum -c nandroid.md5", backup_path); if (0 != __system(tmp)) return print_and_error("MD5 mismatch!\n"); } int ret; if (restore_boot && NULL != volume_for_path("/boot") && 0 != (ret = nandroid_restore_partition(backup_path, "/boot"))) return ret; if (backup_recovery && 0 != (ret = nandroid_restore_partition(backup_path, "/recovery"))) return ret; struct stat s; Volume *vol = volume_for_path("/wimax"); if (restore_wimax && vol != NULL && 0 == stat(vol->device, &s)) { char serialno[PROPERTY_VALUE_MAX]; serialno[0] = 0; property_get("ro.serialno", serialno, ""); sprintf(tmp, "%s/wimax.%s.img", backup_path, serialno); struct stat st; if (0 != stat(tmp, &st)) { ui_print("WARNING: WiMAX partition exists, but nandroid\n"); ui_print(" backup does not contain WiMAX image.\n"); ui_print(" You should create a new backup to\n"); ui_print(" protect your WiMAX keys.\n"); } else { ui_print("Erasing WiMAX before restore...\n"); if (0 != (ret = format_volume("/wimax"))) return print_and_error("Error while formatting wimax!\n"); ui_print("Restoring WiMAX image...\n"); if (0 != (ret = restore_raw_partition(vol->fs_type, vol->device, tmp))) return ret; } } // restore of raw efs image files (efs_time-stamp.img) is done elsewhere // as it needs to pass in a filename (instead of a folder) as backup_path // this could be done here since efs is processed alone, but must be done before md5 checksum! if (backup_efs == RESTORE_EFS_TAR && 0 != (ret = nandroid_restore_partition(backup_path, "/efs"))) return ret; if (backup_modem == RAW_IMG_FILE && 0 != (ret = nandroid_restore_partition(backup_path, "/modem"))) return ret; else if (backup_modem == RAW_BIN_FILE) { sprintf(tmp, "%s/modem.bin", backup_path); custom_restore_raw_handler(tmp, "/modem"); } if (restore_system && 0 != (ret = nandroid_restore_partition(backup_path, "/system"))) return ret; if (is_custom_backup && backup_preload) { if (0 != (ret = nandroid_restore_partition(backup_path, "/preload"))) { ui_print("Failed to restore /preload!\n"); return ret; } } else if (!is_custom_backup #ifdef PHILZ_TOUCH_RECOVERY && nandroid_add_preload #endif ) { if (restore_system && 0 != (ret = nandroid_restore_partition(backup_path, "/preload"))) { ui_print("Failed to restore preload! Try to disable it.\n"); ui_print("Skipping /preload...\n"); //return ret; } } if (restore_data && 0 != (ret = nandroid_restore_partition(backup_path, "/data"))) return ret; if (has_datadata()) { if (restore_data && 0 != (ret = nandroid_restore_partition(backup_path, "/datadata"))) return ret; } if (restore_data && 0 != (ret = nandroid_restore_partition_extended(backup_path, "/sdcard/.android_secure", 0))) return ret; if (restore_cache && 0 != (ret = nandroid_restore_partition_extended(backup_path, "/cache", 0))) return ret; if (restore_sdext && 0 != (ret = nandroid_restore_partition(backup_path, "/sd-ext"))) return ret; sync(); ui_set_background(BACKGROUND_ICON_NONE); ui_reset_progress(); ui_print("\nRestore complete!\n"); return 0; }
int nandroid_restore(const char* backup_path, int restore_boot, int restore_system, int restore_data, int restore_cache, int restore_sdext, int restore_wimax) { ui_set_background(BACKGROUND_ICON_INSTALLING); ui_show_indeterminate_progress(); nandroid_files_total = 0; if (ensure_path_mounted(backup_path) != 0) return print_and_error("挂载分区失败\n"); char tmp[PATH_MAX]; ui_print("检查MD5 校验值...\n"); sprintf(tmp, "cd %s && md5sum -c nandroid.md5", backup_path); if (0 != __system(tmp)) return print_and_error("MD5不合法\n"); int ret; if (restore_boot) { if (NULL != volume_for_path("/boot") && 0 != (ret = nandroid_restore_partition(backup_path, "/boot"))) return ret; if (NULL != volume_for_path("/uboot") && 0 != (ret = nandroid_restore_partition(backup_path, "/uboot"))) return ret; if (NULL != volume_for_path("/recovery") && 0 != (ret = nandroid_restore_partition(backup_path, "/recovery"))) return ret; } struct stat s; Volume *vol = volume_for_path("/wimax"); if (restore_wimax && vol != NULL && 0 == stat(vol->device, &s)) { char serialno[PROPERTY_VALUE_MAX]; serialno[0] = 0; property_get("ro.serialno", serialno, ""); sprintf(tmp, "%s/wimax.%s.img", backup_path, serialno); struct stat st; if (0 != stat(tmp, &st)) { ui_print("警告: WiMAX分区存在,但是\n"); ui_print(" 不存在可恢复的WiMAX 镜像.\n"); ui_print(" 亦需要重新做一个备份 \n"); ui_print(" 来保护你的WiMAX keys.\n"); } else { ui_print("恢复之前先清除WiMAX...\n"); if (0 != (ret = format_volume("/wimax"))) return print_and_error("抹掉wimax失败!\n"); ui_print("恢复WiMAX 镜像...\n"); if (0 != (ret = restore_raw_partition(vol->fs_type, vol->device, tmp))) return ret; } } if (restore_system && 0 != (ret = nandroid_restore_partition(backup_path, "/system"))) return ret; if (restore_data && 0 != (ret = nandroid_restore_partition(backup_path, "/data"))) return ret; if (has_datadata()) { if (restore_data && 0 != (ret = nandroid_restore_partition(backup_path, "/datadata"))) return ret; } if (restore_data && 0 != (ret = nandroid_restore_partition_extended(backup_path, "/sdcard/.android_secure", 0))) return ret; if (restore_cache && 0 != (ret = nandroid_restore_partition_extended(backup_path, "/cache", 0))) return ret; if (restore_sdext && 0 != (ret = nandroid_restore_partition(backup_path, "/sd-ext"))) return ret; sync(); ui_set_background(BACKGROUND_ICON_NONE); ui_reset_progress(); ui_print("\n恢复完成!\n"); return 0; }
int nandroid_restore(const char* backup_path, int restore_boot, int restore_system, int restore_data, int restore_cache, int restore_sdext, int restore_wimax) { ui_set_background(BACKGROUND_ICON_INSTALLING); ui_show_indeterminate_progress(); yaffs_files_total = 0; if (ensure_path_mounted("/sdcard") != 0) return print_and_error("Can't mount /sdcard\n"); char tmp[PATH_MAX]; ui_print("Checking MD5 sums...\n"); sprintf(tmp, "cd %s && md5sum -c nandroid.md5", backup_path); if (0 != __system(tmp)) return print_and_error("MD5 mismatch!\n"); int ret; if (restore_boot && NULL != volume_for_path("/boot") && 0 != (ret = nandroid_restore_partition(backup_path, "/boot"))) return ret; struct stat s; Volume *vol = volume_for_path("/wimax"); if (restore_wimax && vol != NULL && 0 == stat(vol->device, &s)) { char serialno[PROPERTY_VALUE_MAX]; serialno[0] = 0; property_get("ro.serialno", serialno, ""); sprintf(tmp, "%s/wimax.%s.img", backup_path, serialno); struct stat st; if (0 != stat(tmp, &st)) { ui_print("WARNING: WiMAX partition exists, but nandroid\n"); ui_print(" backup does not contain WiMAX image.\n"); ui_print(" You should create a new backup to\n"); ui_print(" protect your WiMAX keys.\n"); } else { ui_print("Erasing WiMAX before restore...\n"); if (0 != (ret = format_volume("/wimax"))) return print_and_error("Error while formatting wimax!\n"); ui_print("Restoring WiMAX image...\n"); if (0 != (ret = restore_raw_partition(vol->fs_type, vol->device, tmp))) return ret; } } if (restore_system && 0 != (ret = nandroid_restore_partition(backup_path, "/system"))) return ret; if (restore_data && 0 != (ret = nandroid_restore_partition(backup_path, "/data"))) return ret; if (has_datadata()) { if (restore_data && 0 != (ret = nandroid_restore_partition(backup_path, "/datadata"))) return ret; } if (restore_data && 0 != (ret = nandroid_restore_partition_extended(backup_path, "/sdcard/.android_secure", 0))) return ret; if (restore_cache && 0 != (ret = nandroid_restore_partition_extended(backup_path, "/cache", 0))) return ret; #ifdef RECOVERY_HAVE_SD_EXT if (restore_sdext && 0 != (ret = nandroid_restore_partition(backup_path, "/sd-ext"))) return ret; #endif sync(); ui_set_background(BACKGROUND_ICON_NONE); ui_reset_progress(); ui_print("\nRestore complete!\n"); return 0; }