int format_root_device(const char *root) { /* Don't try to format a mounted device. */ int ret = ensure_root_path_unmounted(root); if (ret < 0) { LOGD(LOG_TAG "format_root_device: can't unmount \"%s\"\n", root); return -1; } if (!strcmp(root, "/data")) { int result = make_ext4fs("/emmc@usrdata", 0); if (result != 0) { LOGE("format_volume: make_extf4fs failed on /emmc@usrdata\n"); return -1; } } else if (!strcmp(root, "/cache")) { int result = make_ext4fs("/emmc@cache", 0); if (result != 0) { LOGE("format_volume: make_extf4fs failed on /emmc@cache\n"); return -1; } } return 0; }
void root_menu(int confirm) { if (confirm) { static char** title_headers = NULL; if (title_headers == NULL) { char* headers[] = { "ROOT installed ROM?", " ", "Rooting without the superuser app installed", "does nothing. Please install the superuser app", "from the market! (by ChainsDD)", " ", NULL }; title_headers = prepend_title(headers); } char* items[] = { " No", " OK, give me root!", NULL }; int chosen_item = get_menu_selection(title_headers, items, 1, 0); if (chosen_item != 1) { return; } } char* argv[] = { "/sbin/actroot", NULL }; char* envp[] = { NULL }; ensure_root_path_mounted("SYSTEM:"); remove("/system/recovery-from-boot.p"); int status = runve("/sbin/actroot",argv,envp,1); ensure_root_path_unmounted("SYSTEM:"); return; }
int format_non_mtd_device(const char* root) { // if this is SDEXT:, don't worry about it. if (0 == strcmp(root, "SDEXT:")) { struct stat st; if (0 != stat(SDEXT_DEVICE, &st)) { ui_print("No app2sd partition found. Skipping format of /sd-ext.\n"); return 0; } } char path[PATH_MAX]; translate_root_path(root, path, PATH_MAX); if (0 != ensure_root_path_mounted(root)) { ui_print("Error mounting %s!\n", path); ui_print("Skipping format...\n"); return 0; } static char tmp[PATH_MAX]; sprintf(tmp, "rm -rf %s/*", path); __system(tmp); sprintf(tmp, "rm -rf %s/.*", path); __system(tmp); ensure_root_path_unmounted(root); return 0; }
/* Image backup functions */ int nandroid_backup_partition_extended(const char* backup_path, char* root, int umount_when_finished) { int ret = 0; char mount_point[PATH_MAX]; translate_root_path(root, mount_point, PATH_MAX); char* name = basename(mount_point); struct stat file_info; mkyaffs2image_callback callback = NULL; if (0 != stat("/sdcard/ebrecovery/.hidenandroidprogress", &file_info)) { callback = yaffs_callback; } ui_print("Backing up %s...\n", name); if (0 != (ret = ensure_root_path_mounted(root) != 0)) { ui_print("Can't mount %s!\n", mount_point); return ret; } compute_directory_stats(mount_point); char tmp[PATH_MAX]; sprintf(tmp, "%s/%s.img", backup_path, name); ret = mkyaffs2image(mount_point, tmp, 0, callback); if (umount_when_finished) { ensure_root_path_unmounted(root); } if (0 != ret) { ui_print("Error while making a yaffs2 image of %s!\n", mount_point); return ret; } return 0; }
void wipe_battery_stats() { ui_print("Wiping battery stats...\n"); ensure_root_path_mounted("DATA:"); remove("/data/system/batterystats.bin"); ensure_root_path_unmounted("DATA:"); ui_print("Done.\n"); }
void disable_OTA() { ui_print("\nDisabling OTA updates in ROM..."); ensure_root_path_mounted("SYSTEM:"); remove("/system/etc/security/otacerts.zip"); remove("/cache/signed-*.*"); ui_print("\nOTA-updates disabled.\n"); ensure_root_path_unmounted("SYSTEM:"); return; }
int tarbackup_restore_partition_extended(const char* backup_path, const char* root, int umount_when_finished) { int ret; char mount_point[PATH_MAX]; translate_root_path(root, mount_point, PATH_MAX); char* name = basename(mount_point); char tmp[PATH_MAX]; sprintf(tmp, "%s/%s.tar", backup_path, name); struct stat file_info; if (0 != (ret = statfs(tmp, &file_info))) { ui_print("%s.tar not found. Skipping restore of %s.\n", name, mount_point); return 0; } ensure_directory(mount_point); ui_print("Restoring %s...\n", name); if (0 != (ret = ensure_root_path_unmounted(root))) { ui_print("Can't unmount %s!\n", mount_point); return ret; } if (0 != (ret = format_root_device(root))) { ui_print("Error while formatting %s!\n", root); return ret; } if (0 != (ret = ensure_root_path_mounted(root))) { ui_print("Can't mount %s!\n", mount_point); return ret; } sprintf(tmp, "tar -x -f %s/%s.tar", backup_path, name); if (0 != __system(tmp)) { ui_print("Error while restoring %s!\n", mount_point); return ret; } if (umount_when_finished) { ensure_root_path_unmounted(root); } return 0; }
int detect_internal_fs(const char *root_path) { RootInfo *info = get_root_info_for_path(root_path); if (info == NULL || info->device == NULL) { LOGW("detect_internal_fs: can't resolve \"%s\"\n", root_path); return -1; } /* Don't try to unmount a mounted device. */ int ret = ensure_root_path_unmounted(root_path); if (ret < 0) { LOGW("detect_internal_fs: can't unmount \"%s\"\n", root_path); return ret; } /* Consistently try to mount for different types of file systems. */ int i; for (i=0; i<NUM_FSYSTEMS; i++) { LOGW("detect_internal_fs: Try to mount: %s as %s (%s) - ", root_path, g_fs_options[i].filesystem, g_fs_options[i].filesystem_options); if (mount_internal(info->device, info->mount_point, g_fs_options[i].filesystem, g_fs_options[i].filesystem_options) == 0) { LOGW("success\n"); /* success * set type of fs & options for root_path */ info->filesystem = g_fs_options[i].filesystem; info->filesystem_options = g_fs_options[i].filesystem_options; // unmount partition ensure_root_path_unmounted(root_path); return 0; } } // can't determine return -1; }
int nandroid_restore_partition_extended(const char* backup_path, const char* root, int umount_when_finished) { int ret; char mount_point[PATH_MAX]; translate_root_path(root, mount_point, PATH_MAX); char* name = basename(mount_point); char tmp[PATH_MAX]; sprintf(tmp, "%s/%s.img", backup_path, name); struct stat file_info; if (0 != (ret = statfs(tmp, &file_info))) { ui_print("%s.img not found. Skipping restore of %s.\n", name, mount_point); return 0; } ensure_directory(mount_point); unyaffs_callback callback = NULL; if (0 != stat("/sdcard/ebrecovery/.hidenandroidprogress", &file_info)) { callback = yaffs_callback; } ui_print("Restoring %s...\n", name); /* if (0 != (ret = ensure_root_path_unmounted(root))) { ui_print("Can't unmount %s!\n", mount_point); return ret; } */ if (0 != (ret = format_root_device(root))) { ui_print("Error while formatting %s!\n", root); return ret; } if (0 != (ret = ensure_root_path_mounted(root))) { ui_print("Can't mount %s!\n", mount_point); return ret; } if (0 != (ret = unyaffs(tmp, mount_point, callback))) { ui_print("Error while restoring %s!\n", mount_point); return ret; } if (umount_when_finished) { ensure_root_path_unmounted(root); } return 0; }
int format_root_device(const char *root) { /* Don't try to format a mounted device. */ int ret = ensure_root_path_unmounted(root); if (ret < 0) { LOGD(TAG "format_root_device: can't unmount \"%s\"\n", root); return false; } #if 1 int fd; struct msdc_ioctl msdc_io; fd = open("/dev/misc-sd", O_RDONLY); if (fd < 0) { LOGE("open: /dev/misc-sd failed\n"); return -1; } msdc_io.opcode = MSDC_ERASE_PARTITION; if (!strcmp(root, "/cache")) { msdc_io.buffer = (unsigned int*) "cache"; msdc_io.total_size = 6; } else if (!strcmp(root, "/data")) { msdc_io.buffer = (unsigned int*) "usrdata"; msdc_io.total_size = 8; } ioctl(fd, 0, &msdc_io); close(fd); #endif if (!strcmp(root, "/data")) { int result = make_ext4fs("/emmc@usrdata", 0, 0, 0); if (result != 0) { LOGE("format_volume: make_extf4fs failed on /emmc@usrdata\n"); return -1; } } return 0; }
/* TAR backup functions */ int tarbackup_backup_partition_extended(const char* backup_path, char* root, int umount_when_finished) { char mount_point[PATH_MAX]; translate_root_path(root, mount_point, PATH_MAX); char* name = basename(mount_point); ui_print("Backing up %s...\n", name); if (0 != ensure_root_path_mounted(root)) { ui_print("Can't mount partition for backup!\n"); return -1; } char tmp[PATH_MAX]; sprintf(tmp, "tar -c --exclude=*RFS_LOG.LO* -f %s/%s.tar %s", backup_path, name, get_mount_point_for_root(root)+1); int ret = __system(tmp); if (umount_when_finished) { ensure_root_path_unmounted(root); } if (0 != ret) { ui_print("Error while making image of %s!\n", mount_point); return ret; } return 0; }
void show_partition_menu() { static char* headers[] = { "Mounts and Storage Menu", "", NULL }; typedef char* string; string mounts[MOUNTABLE_COUNT][3] = { { "mount /system", "unmount /system", "SYSTEM:" }, { "mount /data", "unmount /data", "DATA:" }, { "mount /dbdata", "unmount /dbdata", "DATADATA:" }, { "mount /cache", "unmount /cache", "CACHE:" }, { "mount /sdcard", "unmount /sdcard", "SDCARD:" }, { "mount /sd-ext", "unmount /sd-ext", "SDEXT:" }, { "", "", "" }, }; string mtds[MTD_COUNT][2] = { { "format system", "SYSTEM:" }, { "format data", "DATA:" }, { "format dbdata", "DATADATA:" }, { "format cache", "CACHE:" }, { "", "" }, }; string conv_mtds[MTD_COUNT][3] = { { "convert system", "SYSTEM:", "**" }, { "convert data", "DATA:", "**" }, { "convert dbdata", "DATADATA:", "**" }, { "convert cache", "CACHE:", "**" }, { "", "", "" }, }; string mmcs[MMC_COUNT][3] = { { "format sdcard", "SDCARD:" }, { "format sd-ext", "SDEXT:" }, { "", "" }, }; static char* confirm_format = "Confirm format?"; static char* confirm = "Yes - Format"; for (;;) { int ismounted[MOUNTABLE_COUNT]; int i; static string options[MOUNTABLE_COUNT + MTD_COUNT + MTD_COUNT + MMC_COUNT + 1 + 1]; // mountables, format mtds, convet mtds, format mmcs, usb storage, null for (i = 0; i < MOUNTABLE_COUNT; i++) { ismounted[i] = is_root_path_mounted(mounts[i][2]); options[i] = ismounted[i] ? mounts[i][1] : mounts[i][0]; } for (i = 0; i < MTD_COUNT; i++) { options[MOUNTABLE_COUNT + i] = mtds[i][0]; } for (i = 0; i < MTD_COUNT; i++) { options[MOUNTABLE_COUNT + MTD_COUNT + i] = conv_mtds[i][0]; } for (i = 0; i < MMC_COUNT; i++) { options[MOUNTABLE_COUNT + MTD_COUNT*2 + i] = mmcs[i][0]; } options[MOUNTABLE_COUNT + MTD_COUNT*2 + MMC_COUNT] = "mount USB storage"; options[MOUNTABLE_COUNT + MTD_COUNT*2 + MMC_COUNT + 1] = NULL; int chosen_item = get_menu_selection(headers, options, 0); if (chosen_item == GO_BACK) break; if (chosen_item == MOUNTABLE_COUNT + MTD_COUNT*2 + MMC_COUNT) { show_mount_usb_storage_menu(); } else if (chosen_item < MOUNTABLE_COUNT) { if (ismounted[chosen_item]) { if (0 != ensure_root_path_unmounted(mounts[chosen_item][2])) ui_print("Error unmounting %s!\n", mounts[chosen_item][2]); } else { if (0 != ensure_root_path_mounted(mounts[chosen_item][2])) ui_print("Error mounting %s!\n", mounts[chosen_item][2]); } } else if (chosen_item < MOUNTABLE_COUNT + MTD_COUNT) { chosen_item = chosen_item - MOUNTABLE_COUNT; if (!confirm_selection(confirm_format, confirm)) continue; ui_print("Formatting %s...\n", mtds[chosen_item][1]); if (0 != format_root_device(mtds[chosen_item][1])) ui_print("Error formatting %s!\n", mtds[chosen_item][1]); else ui_print("Done.\n"); } else if (chosen_item < MOUNTABLE_COUNT + MTD_COUNT*2) { chosen_item = chosen_item - MOUNTABLE_COUNT - MTD_COUNT; if (0 == convert_mtd_device(conv_mtds[chosen_item][1], conv_mtds[chosen_item][2])) { ui_print("Done.\n"); detect_root_fs(); } ui_clear_backgroud(); ui_reset_progress(); } else if (chosen_item < MOUNTABLE_COUNT + MTD_COUNT*2 + MMC_COUNT) { chosen_item = chosen_item - MOUNTABLE_COUNT - MTD_COUNT*2; if (!confirm_selection(confirm_format, confirm)) continue; ui_print("Formatting %s...\n", mmcs[chosen_item][1]); if (0 != format_non_mtd_device(mmcs[chosen_item][1])) ui_print("Error formatting %s!\n", mmcs[chosen_item][1]); else ui_print("Done.\n"); } } }
/* write_raw_image <src-image> <dest-root> */ static int cmd_write_raw_image(const char *name, void *cookie, int argc, const char *argv[]) { UNUSED(cookie); CHECK_WORDS(); if (argc != 2) { LOGE("Command %s requires exactly two arguments\n", name); return 1; } // Use 10% of the progress bar (20% post-verification) by default const char *src_root_path = argv[0]; const char *dst_root_path = argv[1]; ui_print("Writing %s...\n", dst_root_path); if (!gDidShowProgress) ui_show_progress(DEFAULT_IMAGE_PROGRESS_FRACTION, 0); /* Find the source image, which is probably in a package. */ if (!is_package_root_path(src_root_path)) { LOGE("Command %s: non-package source path \"%s\" not yet supported\n", name, src_root_path); return 255; } /* Get the package. */ char srcpathbuf[PATH_MAX]; const char *src_path; const ZipArchive *package; src_path = translate_package_root_path(src_root_path, srcpathbuf, sizeof(srcpathbuf), &package); if (src_path == NULL) { LOGE("Command %s: bad source path \"%s\"\n", name, src_root_path); return 1; } /* Get the entry. */ const ZipEntry *entry = mzFindZipEntry(package, src_path); if (entry == NULL) { LOGE("Missing file %s\n", src_path); return 1; } /* Unmount the destination root if it isn't already. */ int ret = ensure_root_path_unmounted(dst_root_path); if (ret < 0) { LOGE("Can't unmount %s\n", dst_root_path); return 1; } /* Open the partition for writing. */ const MtdPartition *partition = get_root_mtd_partition(dst_root_path); if (partition == NULL) { LOGE("Can't find %s\n", dst_root_path); return 1; } MtdWriteContext *context = mtd_write_partition(partition); if (context == NULL) { LOGE("Can't open %s\n", dst_root_path); return 1; } /* Extract and write the image. */ bool ok = mzProcessZipEntryContents(package, entry, write_raw_image_process_fn, context); if (!ok) { LOGE("Error writing %s\n", dst_root_path); mtd_write_close(context); return 1; } if (mtd_erase_blocks(context, -1) == (off_t) -1) { LOGE("Error finishing %s\n", dst_root_path); mtd_write_close(context); return -1; } if (mtd_write_close(context)) { LOGE("Error closing %s\n", dst_root_path); return -1; } return 0; }
void show_advanced_menu() { static char* headers[] = { "Advanced and Debugging Menu", "", NULL }; static char* list[] = { "Reboot Recovery", "Wipe Dalvik Cache", "Wipe Battery Stats", "Wipe /data/userinit script", "Report Error", "Key Test", #ifndef BOARD_HAS_SMALL_RECOVERY "Partition SD Card", "Fix Permissions", #endif "Create image for Odin", "---Flash Kernel------", "---Flash Recovery----", "Unlock Kernel 4 Flash", "Unlock Recovery 4 Flash", NULL }; for (;;) { int chosen_item = get_menu_selection(headers, list, 0); if (chosen_item == GO_BACK) break; switch (chosen_item) { case 0: __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_RESTART2, "recovery"); break; case 1: { if (0 != ensure_root_path_mounted("DATA:")) break; ensure_root_path_mounted("SDEXT:"); ensure_root_path_mounted("CACHE:"); if (confirm_selection( "Confirm wipe?", "Yes - Wipe Dalvik Cache")) { __system("rm -r /data/dalvik-cache"); __system("rm -r /cache/dalvik-cache"); __system("rm -r /sd-ext/dalvik-cache"); } ensure_root_path_unmounted("DATA:"); ui_print("Dalvik Cache wiped.\n"); break; } case 2: { if (confirm_selection( "Confirm wipe?", "Yes - Wipe Battery Stats")) wipe_battery_stats(); break; } case 3: ui_print("Wiping /data/userinit.sh...\n"); ensure_root_path_mounted("DATA:"); remove("/data/userinit.sh"); ensure_root_path_unmounted("DATA:"); ui_print("Done.\n"); break; case 4: handle_failure(1); break; case 5: { ui_print("Outputting key codes.\n"); ui_print("Go back to end debugging.\n"); int key; int action; do { key = ui_wait_key(); action = device_handle_key(key, 1); ui_print("Key: %d\n", key); } while (action != GO_BACK); break; } case 6: { static char* ext_sizes[] = { "128M", "256M", "512M", "1024M", "2048M", "4096M", "8192M", "16384M", NULL }; static char* swap_sizes[] = { "0M", "32M", "64M", "128M", "256M", NULL }; static char* ext_headers[] = { "Ext Size", "", NULL }; static char* swap_headers[] = { "Swap Size", "", NULL }; int ext_size = get_menu_selection(ext_headers, ext_sizes, 0); if (ext_size == GO_BACK) continue; int swap_size = get_menu_selection(swap_headers, swap_sizes, 0); if (swap_size == GO_BACK) continue; char sddevice[256]; const RootInfo *ri = get_root_info_for_path("SDCARD:"); strcpy(sddevice, ri->device); // we only want the mmcblk, not the partition sddevice[strlen("/dev/block/mmcblkX")] = NULL; char cmd[PATH_MAX]; setenv("SDPATH", sddevice, 1); sprintf(cmd, "sdparted -es %s -ss %s -efs ext3 -s", ext_sizes[ext_size], swap_sizes[swap_size]); ui_print("Partitioning SD Card... please wait...\n"); if (0 == __system(cmd)) ui_print("Done!\n"); else ui_print("An error occured while partitioning your SD Card. Please see /tmp/recovery.log for more details.\n"); break; } case 7: { ensure_root_path_mounted("SYSTEM:"); ensure_root_path_mounted("DATA:"); ui_print("Fixing permissions...\n"); __system("fix_permissions"); ui_print("Done!\n"); break; } case 8: { // create image for Odin dump_odin_image(); break; } case 9: { ui_print("Flashing kernel...\n"); __system("flash_kernel"); ui_print("Done!\n"); break; } case 10: { ui_print("Flashing recovery...\n"); __system("flash_recovery"); ui_print("Done!\n"); break; } case 11: { ui_print("Unlocking Kernel...\n"); __system("unlock_kernel"); ui_print("Done!\n"); break; } case 12: { ui_print("Unlocking Recovery...\n"); __system("unlock_recovery"); ui_print("Done!\n"); break; } } } }
int install_package(const char *root_path) { recovery_status = 0; int status = INSTALL_SUCCESS; ui_set_background(BACKGROUND_ICON_INSTALLING); ui_print("Finding update package...\n"); ui_show_indeterminate_progress(); if (ensure_root_path_mounted(root_path) != 0) { ui_print("Can't mount %s\n", root_path); status = INSTALL_CORRUPT; goto exit; } char path[PATH_MAX] = ""; if (translate_root_path(root_path, path, sizeof(path)) == NULL) { ui_print("Bad path %s\n", root_path); status = INSTALL_CORRUPT; goto exit; } printf("package name = '%s'\t path_len= %d\n",path,strlen(path)); ui_print("Opening update package...\n"); #if 0 int numKeys; RSAPublicKey* loadedKeys = load_keys(PUBLIC_KEYS_FILE, &numKeys); if (loadedKeys == NULL) { LOGE("Failed to load keys\n"); return INSTALL_CORRUPT; } LOGI("%d key(s) loaded from %s\n", numKeys, PUBLIC_KEYS_FILE); // Give verification half the progress bar... ui_print("Verifying update package...\n"); ui_show_progress( VERIFICATION_PROGRESS_FRACTION, VERIFICATION_PROGRESS_TIME); int err; err = verify_file(path, loadedKeys, numKeys); free(loadedKeys); LOGI("verify_file returned %d\n", err); if (err != VERIFY_SUCCESS) { LOGE("signature verification failed\n"); return INSTALL_CORRUPT; } #endif /* Try to open the package. */ int err; ZipArchive zip; err = mzOpenZipArchive(path, &zip); if (err != 0) { ui_print("Can't open %s\n(%s)\n", path, err != -1 ? strerror(err) : "bad"); status = INSTALL_CORRUPT; goto exit; } /* * Verify hw version */ /* if (check_hw_version(&zip)) { ui_print("HW version doesn't match!!!"); status = INSTALL_CORRUPT; mzCloseZipArchive(&zip); goto exit; } */ /* Verify and install the contents of the package. */ ui_print("start update package file\n"); status = handle_update_package(path, &zip); ui_print("install_success!!!\n"); mzCloseZipArchive(&zip); exit: ensure_root_path_unmounted(root_path); if (status != INSTALL_SUCCESS) recovery_status = 1; else recovery_status = 0; return status; }
int format_root_device(const char *root) { /* Be a little safer here; require that "root" is just * a device with no relative path after it. */ const char *c = root; while (*c != '\0' && *c != ':') { c++; } /* if (c[0] != ':' || c[1] != '\0') { LOGW("format_root_device: bad root name \"%s\"\n", root); return -1; } */ const RootInfo *info = get_root_info_for_path(root); if (info == NULL || info->device == NULL) { LOGW("format_root_device: can't resolve \"%s\"\n", root); return -1; } if (info->mount_point != NULL) { /* Don't try to format a mounted device. */ int ret = ensure_root_path_unmounted(root); if (ret < 0) { LOGW("format_root_device: can't unmount \"%s\"\n", root); return ret; } } /* Format the device. */ if (info->device == g_mtd_device) { mtd_scan_partitions(); const MtdPartition *partition; partition = mtd_find_partition_by_name(info->partition_name); if (partition == NULL) { LOGW("format_root_device: can't find mtd partition \"%s\"\n", info->partition_name); return -1; } if (info->filesystem == g_raw || !strcmp(info->filesystem, "yaffs2")) { MtdWriteContext *write = mtd_write_partition(partition); if (write == NULL) { LOGW("format_root_device: can't open \"%s\"\n", root); return -1; } else if (mtd_erase_blocks(write, -1) == (off_t) -1) { LOGW("format_root_device: can't erase \"%s\"\n", root); mtd_write_close(write); return -1; } else if (mtd_write_close(write)) { LOGW("format_root_device: can't close \"%s\"\n", root); return -1; } else { return 0; } } } //Handle MMC device types if (info->device == g_mmc_device) { mmc_scan_partitions(); const MmcPartition *partition; partition = mmc_find_partition_by_name(info->partition_name); if (partition == NULL) { LOGE("format_root_device: can't find mmc partition \"%s\"\n", info->partition_name); return -1; } if (!strcmp(info->filesystem, "ext3")) { if(mmc_format_ext3(partition)) LOGE("\n\"%s\" wipe failed!\n", info->partition_name); } } /* Format rfs filesystem */ if (!strcmp(info->filesystem, "rfs")) { LOGW("format_root_device: %s as rfs\n", info->device); char stl_format[32] = "stl.format "; strcat(stl_format, info->device); if (__system(stl_format) != 0) { LOGE("format_root_device: Can't run STL format [%s]\n", strerror(errno)); return -1; } return 0; } /* Format ext file system */ if (!strncmp(info->filesystem, "ext", 3)) { LOGW("format_root_device: %s as %s\n", info->device, info->filesystem); char ext_format[96]; sprintf(ext_format, "/sbin/mke2fs -T %s -F -j -q -m 0 -b 4096 %s %s", info->filesystem, (info->filesystem[3]=='2')?"":"-O ^huge_file,extent ", info->device); if (__system(ext_format) != 0) { LOGE("format_root_device: Can't run mke2fs [%s]\n", strerror(errno)); return -1; } return 0; } return format_non_mtd_device(root); }
void dumping_odin_image(const char* root) { if (strcmp(get_type_internal_fs(root), "rfs")) { ui_print("You can use this only for RFS filesystem!\n"); return -1; } struct statfs s; if (0 != statfs("/sdcard", &s)) return print_and_error("Unable to stat /sdcard\n"); uint64_t bavail = s.f_bavail; uint64_t bsize = s.f_bsize; uint64_t sdcard_free = bavail * bsize; uint64_t sdcard_free_mb = sdcard_free / (uint64_t)(1024 * 1024); ui_print("SD Card space free: %lluMB\n", sdcard_free_mb); if (sdcard_free_mb < 400) ui_print("There may not be enough free space to complete dump... continuing...\n"); int n_odin_ifile=0; const char* odin_ifile[3] = { "factoryfs.rfs", "datafs.rfs", "cache.rfs" }; char backup_path[PATH_MAX], sdev[32], *st; if (!strcmp(root, "DATA:")) n_odin_ifile = 1; else if (!strcmp(root, "CACHE:")) n_odin_ifile = 2; char tar_file[PATH_MAX]; time_t t = time(NULL); struct tm *tmp = localtime(&t); if (tmp == NULL) { struct timeval tp; gettimeofday(&tp, NULL); sprintf(tar_file, "%d", tp.tv_sec); } else { strftime(tar_file, sizeof(tar_file), "%F.%H.%M.%S", tmp); } ensure_root_path_unmounted(root); if (ensure_root_path_mounted("SDCARD:") != 0) { LOGE ("Can't mount /sdcard\n"); return; } if (0 != __system("mkdir -p /sdcard/ebrecovery/odin/tmp")) { ui_print("Can't create tmp folder for backup\n"); return -1; } strcpy(sdev, get_dev_for_root(root)); if (st = strstr(sdev, "stl")) { memcpy(st, "bml", 3); } else { ui_print("Mistake in device name %s\n", sdev); return -1; } ui_print("Dumping %s..\n", root); sprintf(backup_path, "fdump -t %s /sdcard/ebrecovery/odin/tmp/%s", sdev, odin_ifile[n_odin_ifile]); if (0 != __system(backup_path)) { ui_print("Can't create odin image [%s]\n", odin_ifile[n_odin_ifile]); return -1; } sprintf(backup_path, "cd /sdcard/ebrecovery/odin/tmp && tar -cf ../%s.tar %s", tar_file, odin_ifile[n_odin_ifile]); if (0 != __system(backup_path)) { ui_print("Can't create odin image [%s]\n", odin_ifile[n_odin_ifile]); return -1; } __system("rm -r /sdcard/ebrecovery/odin/tmp"); ui_print("Done\n"); }
void show_partition_menu() { static char* headers[] = { "Mounts and Storage Menu", "", NULL }; typedef char* string; string mounts[MOUNTABLE_COUNT][3] = { { "mount /system", "unmount /system", "SYSTEM:" }, { "mount /data", "unmount /data", "DATA:" }, { "mount /cache", "unmount /cache", "CACHE:" }, { "mount /sdcard", "unmount /sdcard", "SDCARD:" }, #ifdef BOARD_HAS_SDCARD_INTERNAL { "mount /emmc", "unmount /emmc", "SDINTERNAL:" }, #endif { "mount /sd-ext", "unmount /sd-ext", "SDEXT:" } }; string mtds[MTD_COUNT][2] = { { "format boot", "BOOT:" }, { "format system", "SYSTEM:" }, { "format data", "DATA:" }, { "format cache", "CACHE:" }, }; string mmcs[MMC_COUNT][3] = { { "format sdcard", "SDCARD:" }, #ifdef BOARD_HAS_SDCARD_INTERNAL { "format internal sdcard", "SDINTERNAL:" }, #endif { "format sd-ext", "SDEXT:" } }; static char* confirm_format = "Confirm format?"; static char* confirm = "Yes - Format"; for (;;) { int ismounted[MOUNTABLE_COUNT]; int i; static string options[MOUNTABLE_COUNT + MTD_COUNT + MMC_COUNT + 1 + 1]; // mountables, format mtds, format mmcs, usb storage, null for (i = 0; i < MOUNTABLE_COUNT; i++) { ismounted[i] = is_root_path_mounted(mounts[i][2]); options[i] = ismounted[i] ? mounts[i][1] : mounts[i][0]; } for (i = 0; i < MTD_COUNT; i++) { options[MOUNTABLE_COUNT + i] = mtds[i][0]; } for (i = 0; i < MMC_COUNT; i++) { options[MOUNTABLE_COUNT + MTD_COUNT + i] = mmcs[i][0]; } options[MOUNTABLE_COUNT + MTD_COUNT + MMC_COUNT] = "mount USB storage"; options[MOUNTABLE_COUNT + MTD_COUNT + MMC_COUNT + 1] = NULL; int chosen_item = get_menu_selection(headers, options, 0); if (chosen_item == GO_BACK) break; if (chosen_item == MOUNTABLE_COUNT + MTD_COUNT + MMC_COUNT) { show_mount_usb_storage_menu(); } else if (chosen_item < MOUNTABLE_COUNT) { if (ismounted[chosen_item]) { if (0 != ensure_root_path_unmounted(mounts[chosen_item][2])) ui_print("Error unmounting %s!\n", mounts[chosen_item][2]); } else { if (0 != ensure_root_path_mounted(mounts[chosen_item][2])) ui_print("Error mounting %s!\n", mounts[chosen_item][2]); } } else if (chosen_item < MOUNTABLE_COUNT + MTD_COUNT) { chosen_item = chosen_item - MOUNTABLE_COUNT; if (!confirm_selection(confirm_format, confirm)) continue; ui_print("Formatting %s...\n", mtds[chosen_item][1]); if (0 != format_root_device(mtds[chosen_item][1])) ui_print("Error formatting %s!\n", mtds[chosen_item][1]); else ui_print("Done.\n"); } else if (chosen_item < MOUNTABLE_COUNT + MTD_COUNT + MMC_COUNT) { chosen_item = chosen_item - MOUNTABLE_COUNT - MTD_COUNT; if (!confirm_selection(confirm_format, confirm)) continue; ui_print("Formatting %s...\n", mmcs[chosen_item][1]); if (0 != format_unknown_device(mmcs[chosen_item][1])) ui_print("Error formatting %s!\n", mmcs[chosen_item][1]); else ui_print("Done.\n"); } } }
int write_update_for_bootloader( const char *update, int update_length, int bitmap_width, int bitmap_height, int bitmap_bpp, const char *busy_bitmap, const char *fail_bitmap) { if (ensure_root_path_unmounted(CACHE_NAME)) { LOGE("Can't unmount %s\n", CACHE_NAME); return -1; } const MtdPartition *part = get_root_mtd_partition(CACHE_NAME); if (part == NULL) { LOGE("Can't find %s\n", CACHE_NAME); return -1; } MtdWriteContext *write = mtd_write_partition(part); if (write == NULL) { LOGE("Can't open %s\n(%s)\n", CACHE_NAME, strerror(errno)); return -1; } /* Write an invalid (zero) header first, to disable any previous * update and any other structured contents (like a filesystem), * and as a placeholder for the amount of space required. */ struct update_header header; memset(&header, 0, sizeof(header)); const ssize_t header_size = sizeof(header); if (mtd_write_data(write, (char*) &header, header_size) != header_size) { LOGE("Can't write header to %s\n(%s)\n", CACHE_NAME, strerror(errno)); mtd_write_close(write); return -1; } /* Write each section individually block-aligned, so we can write * each block independently without complicated buffering. */ memcpy(&header.MAGIC, UPDATE_MAGIC, UPDATE_MAGIC_SIZE); header.version = UPDATE_VERSION; header.size = header_size; off_t image_start_pos = mtd_erase_blocks(write, 0); header.image_length = update_length; if ((int) header.image_offset == -1 || mtd_write_data(write, update, update_length) != update_length) { LOGE("Can't write update to %s\n(%s)\n", CACHE_NAME, strerror(errno)); mtd_write_close(write); return -1; } off_t busy_start_pos = mtd_erase_blocks(write, 0); header.image_offset = mtd_find_write_start(write, image_start_pos); header.bitmap_width = bitmap_width; header.bitmap_height = bitmap_height; header.bitmap_bpp = bitmap_bpp; int bitmap_length = (bitmap_bpp + 7) / 8 * bitmap_width * bitmap_height; header.busy_bitmap_length = busy_bitmap != NULL ? bitmap_length : 0; if ((int) header.busy_bitmap_offset == -1 || mtd_write_data(write, busy_bitmap, bitmap_length) != bitmap_length) { LOGE("Can't write bitmap to %s\n(%s)\n", CACHE_NAME, strerror(errno)); mtd_write_close(write); return -1; } off_t fail_start_pos = mtd_erase_blocks(write, 0); header.busy_bitmap_offset = mtd_find_write_start(write, busy_start_pos); header.fail_bitmap_length = fail_bitmap != NULL ? bitmap_length : 0; if ((int) header.fail_bitmap_offset == -1 || mtd_write_data(write, fail_bitmap, bitmap_length) != bitmap_length) { LOGE("Can't write bitmap to %s\n(%s)\n", CACHE_NAME, strerror(errno)); mtd_write_close(write); return -1; } mtd_erase_blocks(write, 0); header.fail_bitmap_offset = mtd_find_write_start(write, fail_start_pos); /* Write the header last, after all the blocks it refers to, so that * when the magic number is installed everything is valid. */ if (mtd_write_close(write)) { LOGE("Can't finish writing %s\n(%s)\n", CACHE_NAME, strerror(errno)); return -1; } write = mtd_write_partition(part); if (write == NULL) { LOGE("Can't reopen %s\n(%s)\n", CACHE_NAME, strerror(errno)); return -1; } if (mtd_write_data(write, (char*) &header, header_size) != header_size) { LOGE("Can't rewrite header to %s\n(%s)\n", CACHE_NAME, strerror(errno)); mtd_write_close(write); return -1; } if (mtd_erase_blocks(write, 0) != image_start_pos) { LOGE("Misalignment rewriting %s\n(%s)\n", CACHE_NAME, strerror(errno)); mtd_write_close(write); return -1; } if (mtd_write_close(write)) { LOGE("Can't finish header of %s\n(%s)\n", CACHE_NAME, strerror(errno)); return -1; } return 0; }
void show_multi_boot_menu() { static char* headers[] = { "MultiBoot Menu", "", NULL }; static char* list[] = { "~~~> Go Back <~~~", "Switch ROM", "Backup Current ROM", "Switch Kernel", "Backup Data", "Restore Data", NULL }; for (;;) { create_rom_dirs(); int chosen_item = get_menu_selection(headers, list, 0); if (chosen_item == GO_BACK) break; switch (chosen_item) { case 0: { return; break; } case 1: { if (ensure_root_path_mounted("SDCARD:") != 0) { LOGE ("Can't mount /sdcard\n"); return; } static char* advancedheaders1[] = { "Choose Which ROM to Activate", NULL }; char* file = choose_file_menu("/sdcard/Android/data/g3mod/roms/", NULL, advancedheaders1); if (file == NULL) return; static char* headers[] = { "Activating ROM", "", NULL }; static char* confirm_restore = "Confirm activate?"; if (confirm_selection(confirm_restore, "Yes - Activate ROM")) { nandroid_restore_system(file,1); } if (0 != ensure_root_path_mounted("DATA:")) break; ensure_root_path_mounted("SDEXT:"); ensure_root_path_mounted("CACHE:"); __system("rm -r /data/dalvik-cache"); __system("rm -r /cache/dalvik-cache"); __system("rm -r /sd-ext/dalvik-cache"); ensure_root_path_unmounted("DATA:"); ui_print("Dalvik Cache wiped.\n"); show_choose_kernel_menu(); break; } case 2: { backup_rom(); break; } case 3: { show_choose_kernel_menu(); break; } case 4: { backup_data(); break; } case 5: { if (ensure_root_path_mounted("SDCARD:") != 0) { LOGE ("Can't mount /sdcard\n"); return; } static char* advancedheaders1[] = { "Choose Which Data to Restore", NULL }; char* file = choose_file_menu("/sdcard/Android/data/g3mod/data/", NULL, advancedheaders1); if (file == NULL) return; static char* headers[] = { "Restoring Data", "", NULL }; static char* confirm_restore = "Confirm restore?"; if (confirm_selection(confirm_restore, "Yes - Restore Data")) { nandroid_restore_data(file,1); nandroid_restore_sd(file,1); nandroid_restore_androidSecure(file,1); } break; } } } }
void show_wipe_menu() { static char* headers[] = { "Wipe Menu", "", NULL }; static char* list[] = { "~~~> Go Back <~~~", "Data / Factory Reset", "Cache", "Wipe Dalvik Cache", "Wipe Battery Stats", NULL }; for (;;) { int chosen_item = get_menu_selection(headers, list, 0); if (chosen_item == GO_BACK) break; switch (chosen_item) { case 0: { return; break; } case 1: { wipe_data1(ui_text_visible()); if (!ui_text_visible()) return; break; } case 2: { if (confirm_selection("Confirm wipe?", "Yes - Wipe Cache")) { ui_print("\n-- Wiping cache...\n"); erase_root1("CACHE:"); ui_print("Cache wipe complete.\n"); if (!ui_text_visible()) return; } break; } case 3: { if (0 != ensure_root_path_mounted("DATA:")) break; ensure_root_path_mounted("SDEXT:"); ensure_root_path_mounted("CACHE:"); if (confirm_selection( "Confirm wipe?", "Yes - Wipe Dalvik Cache")) { __system("rm -r /data/dalvik-cache"); __system("rm -r /cache/dalvik-cache"); __system("rm -r /sd-ext/dalvik-cache"); } ensure_root_path_unmounted("DATA:"); ui_print("Dalvik Cache wiped.\n"); break; } case 4: { if (confirm_selection( "Confirm wipe?", "Yes - Wipe Battery Stats")) wipe_battery_stats(); break; } } } }
void wipe_battery_stats() { ensure_root_path_mounted("DATA:"); remove("/data/system/batterystats.bin"); ensure_root_path_unmounted("DATA:"); }
int format_root_device(const char *root) { /* Be a little safer here; require that "root" is just * a device with no relative path after it. */ const char *c = root; while (*c != '\0' && *c != ':') { c++; } if (c[0] != ':' || c[1] != '\0') { LOGW("format_root_device: bad root name \"%s\"\n", root); return -1; } const RootInfo *info = get_root_info_for_path(root); if (info == NULL || info->device == NULL) { LOGW("format_root_device: can't resolve \"%s\"\n", root); return -1; } if (info->mount_point != NULL) { /* Don't try to format a mounted device. */ int ret = ensure_root_path_unmounted(root); if (ret < 0) { LOGW("format_root_device: can't unmount \"%s\"\n", root); return ret; } } /* Format the device. */ if (info->device == g_mtd_device) { mtd_scan_partitions(); const MtdPartition *partition; partition = mtd_find_partition_by_name(info->partition_name); if (partition == NULL) { LOGW("format_root_device: can't find mtd partition \"%s\"\n", info->partition_name); return -1; } if (info->filesystem == g_raw || !strcmp(info->filesystem, "yaffs2")) { MtdWriteContext *write = mtd_write_partition(partition); if (write == NULL) { LOGW("format_root_device: can't open \"%s\"\n", root); return -1; } else if (mtd_erase_blocks(write, -1) == (off_t) -1) { LOGW("format_root_device: can't erase \"%s\"\n", root); mtd_write_close(write); return -1; } else if (mtd_write_close(write)) { LOGW("format_root_device: can't close \"%s\"\n", root); return -1; } else { return 0; } } } else { return format_non_mtd_device(root); } //TODO: handle other device types (sdcard, etc.) LOGW("format_root_device: can't handle non-mtd device \"%s\"\n", root); return -1; }
int format_root_device(const char *root) { /* Be a little safer here; require that "root" is just * a device with no relative path after it. */ const char *c = root; while (*c != '\0' && *c != ':') { c++; } if (c[0] != ':' || c[1] != '\0') { LOGW("format_root_device: bad root name \"%s\"\n", root); return -1; } const RootInfo *info = get_root_info_for_path(root); if (info == NULL || info->device == NULL) { LOGW("format_root_device: can't resolve \"%s\"\n", root); return -1; } if (info->mount_point != NULL) { /* Don't try to format a mounted device. */ int ret = ensure_root_path_unmounted(root); if (ret < 0) { LOGW("format_root_device: can't unmount \"%s\"\n", root); return ret; } } if (info->filesystem != NULL && strcmp(info->filesystem, "ext2")==0) { LOGW("format: %s\n", info->device); pid_t pid = fork(); if (pid == 0) { char *args[] = {"/xbin/mke2fs", "-b4096", info->device, NULL}; execv("/xbin/mke2fs", args); fprintf(stderr, "E:Can't run mke2fs format [%s]\n", strerror(errno)); _exit(-1); } int status; while (waitpid(pid, &status, WNOHANG) == 0) { ui_print("."); sleep(1); } ui_print("\n"); if (!WIFEXITED(status) || (WEXITSTATUS(status) != 0)) { LOGW("format_root_device: can't erase \"%s\"\n", root); return -1; ui_print("Error running samdroid backup. Backup not performed.\n\n"); } return 0; } /* Format the device. */ if (info->device == g_mtd_device) { mtd_scan_partitions(); const MtdPartition *partition; partition = mtd_find_partition_by_name(info->partition_name); if (partition == NULL) { LOGW("format_root_device: can't find mtd partition \"%s\"\n", info->partition_name); return -1; } if (info->filesystem == g_raw || !strcmp(info->filesystem, "yaffs2")) { MtdWriteContext *write = mtd_write_partition(partition); if (write == NULL) { LOGW("format_root_device: can't open \"%s\"\n", root); return -1; } else if (mtd_erase_blocks(write, -1) == (off_t) -1) { LOGW("format_root_device: can't erase \"%s\"\n", root); mtd_write_close(write); return -1; } else if (mtd_write_close(write)) { LOGW("format_root_device: can't close \"%s\"\n", root); return -1; } else { return 0; } } } //TODO: handle other device types (sdcard, etc.) LOGW("format_root_device: can't handle non-mtd device \"%s\"\n", root); return -1; }