From 38bd760b589d405db9a2e6bf304f07d1b0bae342 Mon Sep 17 00:00:00 2001 From: Dees_Troy Date: Fri, 14 Sep 2012 13:33:53 -0400 Subject: Add wipe functions, compiles in CM7, text shows in UI, zips install Zip install works, had to move mincrypt code into TWRP to prevent a crash when checking the zip signature. Added wipe functions Made it compile in CM7 Made text show up in console and logging --- Android.mk | 3 +- data.cpp | 32 +++- extra-functions.c | 146 ----------------- extra-functions.h | 10 -- gui/action.cpp | 73 ++++----- partition.cpp | 451 ++++++++++++++++++++++++++++++++++++++++----------- partitionmanager.cpp | 156 ++++++++++++++---- partitions.hpp | 18 +- prebuilt/Android.mk | 3 + reboot.c | 2 - recovery.cpp | 8 + roots.cpp | 4 + twinstall.cpp | 95 +---------- twrp-functions.cpp | 164 +++++++++++++++++++ twrp-functions.hpp | 23 +++ ui.cpp | 4 + 16 files changed, 766 insertions(+), 426 deletions(-) create mode 100644 twrp-functions.cpp create mode 100644 twrp-functions.hpp diff --git a/Android.mk b/Android.mk index 6d3be1dec..6c6ee9b28 100644 --- a/Android.mk +++ b/Android.mk @@ -38,7 +38,8 @@ LOCAL_SRC_FILES += \ mtdutils/mtdutils.c \ twinstall.cpp \ twmincrypt/twrsa.c \ - twmincrypt/twsha.c + twmincrypt/twsha.c \ + twrp-functions.cpp ifeq ($(TARGET_RECOVERY_REBOOT_SRC),) LOCAL_SRC_FILES += reboot.c diff --git a/data.cpp b/data.cpp index 8b717f517..896bb1bc6 100644 --- a/data.cpp +++ b/data.cpp @@ -50,8 +50,6 @@ extern "C" void gui_notifyVarChange(const char *name, const char* value); - int get_battery_level(void); - int __system(const char *command); } @@ -761,8 +759,36 @@ int DataManager::GetMagicValue(const string varName, string& value) if (varName == "tw_battery") { char tmp[16]; + static char charging = ' '; + static int lastVal = -1; + static time_t nextSecCheck = 0; + + struct timeval curTime; + gettimeofday(&curTime, NULL); + if (curTime.tv_sec > nextSecCheck) + { + char cap_s[4]; + FILE * cap = fopen("/sys/class/power_supply/battery/capacity","rt"); + if (cap){ + fgets(cap_s, 4, cap); + fclose(cap); + lastVal = atoi(cap_s); + if (lastVal > 100) lastVal = 101; + if (lastVal < 0) lastVal = 0; + } + cap = fopen("/sys/class/power_supply/battery/status","rt"); + if (cap) { + fgets(cap_s, 2, cap); + fclose(cap); + if (cap_s[0] == 'C') + charging = '+'; + else + charging = ' '; + } + nextSecCheck = curTime.tv_sec + 60; + } - sprintf(tmp, "%i%%", get_battery_level()); + sprintf(tmp, "%i%%%c", lastVal, charging); value = tmp; return 0; } diff --git a/extra-functions.c b/extra-functions.c index e01ab83b4..952c091ee 100644 --- a/extra-functions.c +++ b/extra-functions.c @@ -339,102 +339,6 @@ int usb_storage_disable(void) return 0; } -void wipe_dalvik_cache() -{ - //ui_set_background(BACKGROUND_ICON_WIPE); - ensure_path_mounted("/data"); - ensure_path_mounted("/cache"); - ui_print("\n-- Wiping Dalvik Cache Directories...\n"); - __system("rm -rf /data/dalvik-cache"); - ui_print("Cleaned: /data/dalvik-cache...\n"); - __system("rm -rf /cache/dalvik-cache"); - ui_print("Cleaned: /cache/dalvik-cache...\n"); - __system("rm -rf /cache/dc"); - ui_print("Cleaned: /cache/dc\n"); - - struct stat st; - LOGE("TODO: Re-implement wipe dalvik into Partition Manager!\n"); - if (1) //if (0 != stat(sde.blk, &st)) - { - ui_print("/sd-ext not present, skipping\n"); - } else { - __system("mount /sd-ext"); - LOGI("Mounting /sd-ext\n"); - if (stat("/sd-ext/dalvik-cache",&st) == 0) - { - __system("rm -rf /sd-ext/dalvik-cache"); - ui_print("Cleaned: /sd-ext/dalvik-cache...\n"); - } - } - ensure_path_unmounted("/data"); - ui_print("-- Dalvik Cache Directories Wipe Complete!\n\n"); - //ui_set_background(BACKGROUND_ICON_MAIN); - //if (!ui_text_visible()) return; -} - -// BATTERY STATS -void wipe_battery_stats() -{ - ensure_path_mounted("/data"); - struct stat st; - if (0 != stat("/data/system/batterystats.bin", &st)) - { - ui_print("No Battery Stats Found. No Need To Wipe.\n"); - } else { - //ui_set_background(BACKGROUND_ICON_WIPE); - remove("/data/system/batterystats.bin"); - ui_print("Cleared: Battery Stats...\n"); - ensure_path_unmounted("/data"); - } -} - -// ROTATION SETTINGS -void wipe_rotate_data() -{ - //ui_set_background(BACKGROUND_ICON_WIPE); - ensure_path_mounted("/data"); - __system("rm -r /data/misc/akmd*"); - __system("rm -r /data/misc/rild*"); - ui_print("Cleared: Rotatation Data...\n"); - ensure_path_unmounted("/data"); -} - -void fix_perms() -{ - ensure_path_mounted("/data"); - ensure_path_mounted("/system"); - //ui_show_progress(1,30); - ui_print("\n-- Fixing Permissions\n"); - ui_print("This may take a few minutes.\n"); - __system("./sbin/fix_permissions.sh"); - ui_print("-- Done.\n\n"); - //ui_reset_progress(); -} - -int get_battery_level(void) -{ - static int lastVal = -1; - static time_t nextSecCheck = 0; - - struct timeval curTime; - gettimeofday(&curTime, NULL); - if (curTime.tv_sec > nextSecCheck) - { - char cap_s[4]; - FILE * cap = fopen("/sys/class/power_supply/battery/capacity","rt"); - if (cap) - { - fgets(cap_s, 4, cap); - fclose(cap); - lastVal = atoi(cap_s); - if (lastVal > 100) lastVal = 101; - if (lastVal < 0) lastVal = 0; - } - nextSecCheck = curTime.tv_sec + 60; - } - return lastVal; -} - void update_tz_environment_variables() { setenv("TZ", DataManager_GetStrValue(TW_TIME_ZONE_VAR), 1); tzset(); @@ -478,56 +382,6 @@ void run_script(const char *str1, const char *str2, const char *str3, const char //if (!ui_text_visible()) return; } -void install_htc_dumlock(void) -{ - struct statfs fs1, fs2; - int need_libs = 0; - - ui_print("Installing HTC Dumlock to system...\n"); - ensure_path_mounted("/system"); - __system("cp /res/htcd/htcdumlocksys /system/bin/htcdumlock && chmod 755 /system/bin/htcdumlock"); - if (statfs("/system/bin/flash_image", &fs1) != 0) { - ui_print("Installing flash_image...\n"); - __system("cp /res/htcd/flash_imagesys /system/bin/flash_image && chmod 755 /system/bin/flash_image"); - need_libs = 1; - } else - ui_print("flash_image is already installed, skipping...\n"); - if (statfs("/system/bin/dump_image", &fs2) != 0) { - ui_print("Installing dump_image...\n"); - __system("cp /res/htcd/dump_imagesys /system/bin/dump_image && chmod 755 /system/bin/dump_image"); - need_libs = 1; - } else - ui_print("dump_image is already installed, skipping...\n"); - if (need_libs) { - ui_print("Installing libs needed for flash_image and dump_image...\n"); - __system("cp /res/htcd/libbmlutils.so /system/lib && chmod 755 /system/lib/libbmlutils.so"); - __system("cp /res/htcd/libflashutils.so /system/lib && chmod 755 /system/lib/libflashutils.so"); - __system("cp /res/htcd/libmmcutils.so /system/lib && chmod 755 /system/lib/libmmcutils.so"); - __system("cp /res/htcd/libmtdutils.so /system/lib && chmod 755 /system/lib/libmtdutils.so"); - } - ui_print("Installing HTC Dumlock app...\n"); - ensure_path_mounted("/data"); - mkdir("/data/app", 0777); - __system("rm /data/app/com.teamwin.htcdumlock*"); - __system("cp /res/htcd/HTCDumlock.apk /data/app/com.teamwin.htcdumlock.apk"); - sync(); - ui_print("HTC Dumlock is installed.\n"); -} - -void htc_dumlock_restore_original_boot(void) -{ - ui_print("Restoring original boot...\n"); - __system("htcdumlock restore"); - ui_print("Original boot restored.\n"); -} - -void htc_dumlock_reflash_recovery_to_boot(void) -{ - ui_print("Reflashing recovery to boot...\n"); - __system("htcdumlock recovery noreboot"); - ui_print("Recovery is flashed to boot.\n"); -} - void check_and_run_script(const char* script_file, const char* display_name) { // Check for and run startup script if script exists diff --git a/extra-functions.h b/extra-functions.h index 6145e7722..664ca3348 100644 --- a/extra-functions.h +++ b/extra-functions.h @@ -8,22 +8,12 @@ int __system(const char *command); FILE * __popen(const char *program, const char *type); int __pclose(FILE *iop); -void wipe_dalvik_cache(); -void wipe_battery_stats(); -void wipe_rotate_data(); - static long tmplog_offset = 0; void update_tz_environment_variables(); -void fix_perms(); - void run_script(const char *str1, const char *str2, const char *str3, const char *str4, const char *str5, const char *str6, const char *str7, int request_confirm); -void install_htc_dumlock(void); -void htc_dumlock_restore_original_boot(void); -void htc_dumlock_reflash_recovery_to_boot(void); - void check_and_run_script(const char* script_file, const char* display_name); int check_backup_name(int show_error); void twfinish_recovery(const char *send_intent); diff --git a/gui/action.cpp b/gui/action.cpp index a1f7dd3dc..b050febd0 100644 --- a/gui/action.cpp +++ b/gui/action.cpp @@ -19,6 +19,7 @@ #include #include #include "../partitions.hpp" +#include "../twrp-functions.hpp" extern "C" { #include "../common.h" @@ -31,7 +32,6 @@ extern "C" { #include "../twinstall.h" int TWinstall_zip(const char* path, int* wipe_cache); -void fix_perms(); void wipe_dalvik_cache(void); int check_backup_name(int show_error); void wipe_battery_stats(void); @@ -667,62 +667,57 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */) operation_start("Format"); DataManager::SetValue("tw_partition", arg); - int ret_val = 0; + int ret_val = false; if (simulate) { simulate_progress_bar(); } else { if (arg == "data") - PartitionManager.Factory_Reset(); + ret_val = PartitionManager.Factory_Reset(); else if (arg == "battery") - wipe_battery_stats(); + ret_val = PartitionManager.Wipe_Battery_Stats(); else if (arg == "rotate") - wipe_rotate_data(); + ret_val = PartitionManager.Wipe_Rotate_Data(); else if (arg == "dalvik") - wipe_dalvik_cache(); + ret_val = PartitionManager.Wipe_Dalvik_Cache(); else if (arg == "DATAMEDIA") { - LOGE("TODO: Implement formatting of datamedia device!\n"); - ret_val = 1; //format_data_media(); - int has_datamedia, dual_storage; - - DataManager::GetValue(TW_HAS_DATA_MEDIA, has_datamedia); - DataManager::GetValue(TW_HAS_DUAL_STORAGE, dual_storage); - if (has_datamedia && !dual_storage) { - system("umount /sdcard"); - system("mount /data/media /sdcard"); - } + ret_val = PartitionManager.Format_Data(); } else if (arg == "INTERNAL") { int has_datamedia, dual_storage; DataManager::GetValue(TW_HAS_DATA_MEDIA, has_datamedia); if (has_datamedia) { - PartitionManager.Mount_By_Path("/data", 1); - __system("rm -rf /data/media"); - __system("cd /data && mkdir media && chmod 775 media"); - DataManager::GetValue(TW_HAS_DUAL_STORAGE, dual_storage); - if (!dual_storage) { - system("umount /sdcard"); - system("mount /data/media /sdcard"); - } + ret_val = PartitionManager.Wipe_Media_From_Data(); } else { - ret_val = 0; - LOGE("Wipe not implemented yet!\n"); + ret_val = PartitionManager.Wipe_By_Path(DataManager::GetSettingsStoragePath()); } } else if (arg == "EXTERNAL") { - ret_val = 0; - LOGE("Wipe not implemented yet!\n"); + string External_Path; + + DataManager::GetValue(TW_EXTERNAL_PATH, External_Path); + ret_val = PartitionManager.Wipe_By_Path(External_Path); } else - PartitionManager.Wipe_By_Path(arg); + ret_val = PartitionManager.Wipe_By_Path(arg); - if (arg == "/sdcard") { - PartitionManager.Mount_By_Path("/sdcard", 1); - mkdir("/sdcard/TWRP", 0777); - DataManager::Flush(); + if (arg == DataManager::GetSettingsStoragePath()) { + // If we wiped the settings storage path, recreate the TWRP folder and dump the settings + string Storage_Path = DataManager::GetSettingsStoragePath(); + + if (PartitionManager.Mount_By_Path(Storage_Path, true)) { + LOGI("Making TWRP folder and saving settings.\n"); + Storage_Path += "/TWRP"; + mkdir(Storage_Path.c_str(), 0777); + DataManager::Flush(); + } else { + LOGE("Unable to recreate TWRP folder and save settings.\n"); + } } } PartitionManager.Update_System_Details(); - if (ret_val != 0) - ret_val = 1; + if (ret_val) + ret_val = 0; // 0 is success + else + ret_val = 1; // 1 is failure operation_end(ret_val, simulate); return 0; } @@ -770,7 +765,7 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */) if (simulate) { simulate_progress_bar(); } else - fix_perms(); + PartitionManager.Fix_Permissions(); LOGI("fix permissions DONE!\n"); operation_end(0, simulate); @@ -870,7 +865,7 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */) if (simulate) { simulate_progress_bar(); } else - install_htc_dumlock(); + TWFunc::install_htc_dumlock(); operation_end(0, simulate); return 0; @@ -881,7 +876,7 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */) if (simulate) { simulate_progress_bar(); } else - htc_dumlock_restore_original_boot(); + TWFunc::htc_dumlock_restore_original_boot(); operation_end(0, simulate); return 0; @@ -892,7 +887,7 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */) if (simulate) { simulate_progress_bar(); } else - htc_dumlock_reflash_recovery_to_boot(); + TWFunc::htc_dumlock_reflash_recovery_to_boot(); operation_end(0, simulate); return 0; diff --git a/partition.cpp b/partition.cpp index f3c79f7c2..f4fa0d86e 100644 --- a/partition.cpp +++ b/partition.cpp @@ -38,6 +38,8 @@ #include "partitions.hpp" #include "data.hpp" extern "C" { + #include "mtdutils/mtdutils.h" + #include "mtdutils/mounts.h" #include "extra-functions.h" int __system(const char *command); } @@ -52,7 +54,8 @@ TWPartition::TWPartition(void) { Symlink_Path = ""; Symlink_Mount_Point = ""; Mount_Point = ""; - Block_Device = ""; + Actual_Block_Device = ""; + Primary_Block_Device = ""; Alternate_Block_Device = ""; Removable = false; Is_Present = false; @@ -68,6 +71,7 @@ TWPartition::TWPartition(void) { Display_Name = ""; Backup_Name = ""; Backup_FileName = ""; + MTD_Name = ""; Backup_Method = NONE; Has_Data_Media = false; Is_Storage = false; @@ -109,15 +113,19 @@ bool TWPartition::Process_Fstab_Line(string Line, bool Display_Error) { item_index++; } else if (item_index == 1) { // Primary Block Device - if (*ptr != '/') { + if (Fstab_File_System == "mtd" || Fstab_File_System == "yaffs2") { + Primary_Block_Device = ptr; + Find_MTD_Block_Device(Primary_Block_Device); + } else if (*ptr != '/') { if (Display_Error) LOGE("Invalid block device on '%s', '%s', %i\n", Line.c_str(), ptr, index); else LOGI("Invalid block device on '%s', '%s', %i\n", Line.c_str(), ptr, index); return 0; + } else { + Primary_Block_Device = ptr; + Find_Real_Block_Device(Primary_Block_Device, Display_Error); } - Block_Device = ptr; - Find_Real_Block_Device(Block_Device, Display_Error); item_index++; } else if (item_index > 1) { if (*ptr == '/') { @@ -132,6 +140,8 @@ bool TWPartition::Process_Fstab_Line(string Line, bool Display_Error) { // Custom flags, save for later so that new values aren't overwritten by defaults ptr += 6; Flags = ptr; + } else if (strlen(ptr) == 4 && (strncmp(ptr, "NULL", 4) == 0 || strncmp(ptr, "null", 4) == 0 || strncmp(ptr, "null", 4) == 0)) { + // Do nothing } else { // Unhandled data LOGI("Unhandled fstab information: '%s', %i\n", ptr, index); @@ -148,14 +158,17 @@ bool TWPartition::Process_Fstab_Line(string Line, bool Display_Error) { LOGI("Unknown File System: '%s'\n", Fstab_File_System.c_str()); return 0; } else if (Is_File_System(Fstab_File_System)) { + Find_Actual_Block_Device(); Setup_File_System(Display_Error); if (Mount_Point == "/system") { Display_Name = "System"; Wipe_Available_in_GUI = true; + MTD_Name = "system"; } else if (Mount_Point == "/data") { Display_Name = "Data"; Wipe_Available_in_GUI = true; Wipe_During_Factory_Reset = true; + MTD_Name = "userdata"; #ifdef RECOVERY_SDCARD_ON_DATA Has_Data_Media = true; Is_Storage = true; @@ -175,7 +188,7 @@ bool TWPartition::Process_Fstab_Line(string Line, bool Display_Error) { char crypto_blkdev[255]; property_get("ro.crypto.fs_crypto_blkdev", crypto_blkdev, "error"); if (strcmp(crypto_blkdev, "error") != 0) { - DataManager::SetValue(TW_DATA_BLK_DEVICE, Block_Device); + DataManager::SetValue(TW_DATA_BLK_DEVICE, Primary_Block_Device); DataManager::SetValue(TW_IS_DECRYPTED, 1); Is_Encrypted = true; Is_Decrypted = true; @@ -194,6 +207,7 @@ bool TWPartition::Process_Fstab_Line(string Line, bool Display_Error) { Wipe_Available_in_GUI = true; Wipe_During_Factory_Reset = true; Update_Size(Display_Error); + MTD_Name = "cache"; } else if (Mount_Point == "/datadata") { Wipe_During_Factory_Reset = true; Display_Name = "DataData"; @@ -207,8 +221,10 @@ bool TWPartition::Process_Fstab_Line(string Line, bool Display_Error) { } else Update_Size(Display_Error); } else if (Is_Image(Fstab_File_System)) { + Find_Actual_Block_Device(); Setup_Image(Display_Error); if (Mount_Point == "/boot") { + MTD_Name = "boot"; int backup_display_size = (int)(Backup_Size / 1048576LLU); DataManager::SetValue(TW_BACKUP_BOOT_SIZE, backup_display_size); if (Backup_Size == 0) { @@ -217,6 +233,7 @@ bool TWPartition::Process_Fstab_Line(string Line, bool Display_Error) { } else DataManager::SetValue(TW_HAS_BOOT_PARTITION, 1); } else if (Mount_Point == "/recovery") { + MTD_Name = "recovery"; int backup_display_size = (int)(Backup_Size / 1048576LLU); DataManager::SetValue(TW_BACKUP_RECOVERY_SIZE, backup_display_size); if (Backup_Size == 0) { @@ -337,13 +354,6 @@ void TWPartition::Setup_File_System(bool Display_Error) { Can_Be_Mounted = true; Can_Be_Wiped = true; - // Check to see if the block device exists - if (Path_Exists(Block_Device)) { - Is_Present = true; - } else if (!Alternate_Block_Device.empty() && Path_Exists(Alternate_Block_Device)) { - Flip_Block_Device(); - Is_Present = true; - } // Make the mount point folder if it doesn't exist Make_Dir(Mount_Point, Display_Error); Display_Name = Mount_Point.substr(1, Mount_Point.size() - 1); @@ -352,12 +362,6 @@ void TWPartition::Setup_File_System(bool Display_Error) { } void TWPartition::Setup_Image(bool Display_Error) { - if (Path_Exists(Block_Device)) { - Is_Present = true; - } else if (!Alternate_Block_Device.empty() && Path_Exists(Alternate_Block_Device)) { - Flip_Block_Device(); - Is_Present = true; - } Display_Name = Mount_Point.substr(1, Mount_Point.size() - 1); Backup_Name = Display_Name; if (Fstab_File_System == "emmc") @@ -371,9 +375,9 @@ void TWPartition::Setup_Image(bool Display_Error) { Backup_Size = Size; } else { if (Display_Error) - LOGE("Unable to find parition size for '%s'\n", Block_Device.c_str()); + LOGE("Unable to find parition size for '%s'\n", Mount_Point.c_str()); else - LOGI("Unable to find parition size for '%s'\n", Block_Device.c_str()); + LOGI("Unable to find parition size for '%s'\n", Mount_Point.c_str()); } } @@ -400,6 +404,47 @@ void TWPartition::Find_Real_Block_Device(string& Block, bool Display_Error) { } } +bool TWPartition::Find_MTD_Block_Device(string MTD_Name) { + FILE *fp = NULL; + char line[255]; + + fp = fopen("/proc/mtd", "rt"); + if (fp == NULL) { + LOGE("Device does not support /proc/mtd\n"); + return false; + } + + while (fgets(line, sizeof(line), fp) != NULL) + { + char device[32], label[32]; + unsigned long size = 0; + char* fstype = NULL; + int deviceId; + + sscanf(line, "%s %lx %*s %*c%s", device, &size, label); + + // Skip header and blank lines + if ((strcmp(device, "dev:") == 0) || (strlen(line) < 8)) + continue; + + // Strip off the trailing " from the label + label[strlen(label)-1] = '\0'; + + if (strcmp(label, MTD_Name.c_str()) == 0) { + // We found our device + // Strip off the trailing : from the device + device[strlen(device)-1] = '\0'; + if (sscanf(device,"mtd%d", &deviceId) == 1) { + sprintf(device, "/dev/block/mtdblock%d", deviceId); + Primary_Block_Device = device; + } + } + } + fclose(fp); + + return false; +} + bool TWPartition::Get_Size_Via_statfs(bool Display_Error) { struct statfs st; string Local_Path = Mount_Point + "/."; @@ -432,7 +477,7 @@ bool TWPartition::Get_Size_Via_df(bool Display_Error) { if (!Mount(Display_Error)) return false; - min_len = Block_Device.size() + 2; + min_len = Actual_Block_Device.size() + 2; sprintf(command, "df %s > /tmp/dfoutput.txt", Mount_Point.c_str()); __system(command); fp = fopen("/tmp/dfoutput.txt", "rt"); @@ -534,7 +579,7 @@ bool TWPartition::Find_Partition_Size(void) { tmpdevice = "/dev/block/"; tmpdevice += device; - if (tmpdevice == Block_Device || tmpdevice == Alternate_Block_Device) { + if (tmpdevice == Primary_Block_Device || tmpdevice == Alternate_Block_Device) { // Adjust block size to byte size Size = blocks * 1024ULL; fclose(fp); @@ -559,7 +604,7 @@ void TWPartition::Flip_Block_Device(void) { string temp; temp = Alternate_Block_Device; - Block_Device = Alternate_Block_Device; + Primary_Block_Device = Alternate_Block_Device; Alternate_Block_Device = temp; } @@ -590,55 +635,30 @@ bool TWPartition::Mount(bool Display_Error) { } else if (!Can_Be_Mounted) { return false; } - if (Removable) - Check_FS_Type(); - if (Is_Decrypted) { - if (mount(Decrypted_Block_Device.c_str(), Mount_Point.c_str(), Current_File_System.c_str(), 0, NULL) != 0) { - Check_FS_Type(); - if (mount(Decrypted_Block_Device.c_str(), Mount_Point.c_str(), Current_File_System.c_str(), 0, NULL) != 0) { - if (Display_Error) - LOGE("Unable to mount decrypted block device '%s' to '%s'\n", Decrypted_Block_Device.c_str(), Mount_Point.c_str()); - else - LOGI("Unable to mount decrypted block device '%s' to '%s'\n", Decrypted_Block_Device.c_str(), Mount_Point.c_str()); - return false; - } else { - if (Removable) - Update_Size(Display_Error); - return true; - } - } else { - if (Removable) - Update_Size(Display_Error); - return true; - } - } - if (mount(Block_Device.c_str(), Mount_Point.c_str(), Current_File_System.c_str(), 0, NULL) != 0) { - Check_FS_Type(); - if (mount(Block_Device.c_str(), Mount_Point.c_str(), Current_File_System.c_str(), 0, NULL) != 0) { - if (!Alternate_Block_Device.empty() && Path_Exists(Alternate_Block_Device)) { - Flip_Block_Device(); - Check_FS_Type(); - if (mount(Block_Device.c_str(), Mount_Point.c_str(), Current_File_System.c_str(), 0, NULL) != 0) { - if (Display_Error) - LOGE("Unable to mount '%s'\n", Mount_Point.c_str()); - else - LOGI("Unable to mount '%s'\n", Mount_Point.c_str()); - return false; - } else { - if (Removable) - Update_Size(Display_Error); - return true; - } - } else - return false; - } else { - if (Removable) - Update_Size(Display_Error); - return true; + + Find_Actual_Block_Device(); + + // Check the current file system before mounting + Check_FS_Type(); + + if (mount(Actual_Block_Device.c_str(), Mount_Point.c_str(), Current_File_System.c_str(), 0, NULL) != 0) { + if (Display_Error) + LOGE("Unable to mount '%s'\n", Mount_Point.c_str()); + else + LOGI("Unable to mount '%s'\n", Mount_Point.c_str()); + return false; + } else { + if (Removable) + Update_Size(Display_Error); + + if (!Symlink_Mount_Point.empty()) { + string Command; + + Command = "mount " + Symlink_Path + " " + Symlink_Mount_Point; + __system(Command.c_str()); } + return true; } - if (Removable) - Update_Size(Display_Error); return true; } @@ -650,6 +670,9 @@ bool TWPartition::UnMount(bool Display_Error) { if (never_unmount_system == 1 && Mount_Point == "/system") return true; // Never unmount system if you're not supposed to unmount it + if (!Symlink_Mount_Point.empty()) + umount(Symlink_Mount_Point.c_str()); + if (umount(Mount_Point.c_str()) != 0) { if (Display_Error) LOGE("Unable to unmount '%s'\n", Mount_Point.c_str()); @@ -664,33 +687,100 @@ bool TWPartition::UnMount(bool Display_Error) { } bool TWPartition::Wipe() { - LOGI("STUB TWPartition::Wipe\n"); - return 1; + if (!Can_Be_Wiped) { + LOGE("Partition '%s' cannot be wiped.\n", Mount_Point.c_str()); + return false; + } + + if (Has_Data_Media) + return Wipe_Data_Without_Wiping_Media(); + + int check; + DataManager::GetValue(TW_RM_RF_VAR, check); + if (check) + return Wipe_RMRF(); + + if (Current_File_System == "ext4") + return Wipe_EXT4(); + + if (Current_File_System == "ext2" || Current_File_System == "ext3") + return Wipe_EXT23(); + + if (Current_File_System == "vfat") + return Wipe_FAT(); + + if (Current_File_System == "yaffs2") + return Wipe_MTD(); + + LOGE("Unable to wipe '%s' -- unknown file system '%s'\n", Mount_Point.c_str(), Current_File_System.c_str()); + return false; } bool TWPartition::Backup(string backup_folder) { - LOGI("STUB TWPartition::Backup, backup_folder: '%s'\n", backup_folder.c_str()); - return 1; + if (Backup_Method == FILES) + return Backup_Tar(backup_folder); + else if (Backup_Method == DD) + return Backup_DD(backup_folder); + else if (Backup_Method == FLASH_UTILS) + return Backup_Dump_Image(backup_folder); + LOGE("Unknown backup method for '%s'\n", Mount_Point.c_str()); + return false; } bool TWPartition::Restore(string restore_folder) { - LOGI("STUB TWPartition::Restore, restore_folder: '%s'\n", restore_folder.c_str()); - return 1; + if (Backup_Method == FILES) + return Restore_Tar(restore_folder); + else if (Backup_Method == DD) + return Restore_DD(restore_folder); + else if (Backup_Method == FLASH_UTILS) + return Restore_Flash_Image(restore_folder); + LOGE("Unknown restore method for '%s'\n", Mount_Point.c_str()); + return false; } string TWPartition::Backup_Method_By_Name() { - LOGI("STUB TWPartition::Backup_Method_By_Name\n"); - return "STUB"; + if (Backup_Method == NONE) + return "none"; + else if (Backup_Method == FILES) + return "files"; + else if (Backup_Method == DD) + return "dd"; + else if (Backup_Method == FLASH_UTILS) + return "flash_utils"; + else + return "undefined"; + return "ERROR!"; } bool TWPartition::Decrypt(string Password) { LOGI("STUB TWPartition::Decrypt, password: '%s'\n", Password.c_str()); + // Is this needed? return 1; } bool TWPartition::Wipe_Encryption() { - LOGI("STUB TWPartition::Wipe_Encryption\n"); - return 1; + bool Save_Data_Media = Has_Data_Media; + + if (!UnMount(true)) + return false; + + Current_File_System = Fstab_File_System; + Is_Encrypted = false; + Is_Decrypted = false; + Decrypted_Block_Device = ""; + Has_Data_Media = false; + if (Wipe()) { + Has_Data_Media = Save_Data_Media; + if (Has_Data_Media && !Symlink_Mount_Point.empty()) { + Recreate_Media_Folder(); + } + return true; + } else { + Has_Data_Media = Save_Data_Media; + LOGE("Unable to format to remove encryption.\n"); + return false; + } + return false; } void TWPartition::Check_FS_Type() { @@ -704,10 +794,8 @@ void TWPartition::Check_FS_Type() { if (Fstab_File_System == "yaffs2" || Fstab_File_System == "mtd") return; // Running blkid on some mtd devices causes a massive crash - if (Is_Decrypted) - blkCommand = "blkid " + Decrypted_Block_Device + " > /tmp/blkidoutput.txt"; - else - blkCommand = "blkid " + Block_Device + " > /tmp/blkidoutput.txt"; + Find_Actual_Block_Device(); + blkCommand = "blkid " + Actual_Block_Device + " > /tmp/blkidoutput.txt"; __system(blkCommand.c_str()); fp = fopen("/tmp/blkidoutput.txt", "rt"); @@ -764,33 +852,165 @@ void TWPartition::Check_FS_Type() { } bool TWPartition::Wipe_EXT23() { - LOGI("STUB TWPartition::Wipe_EXT23\n"); - return 1; + if (!UnMount(true)) + return false; + + if (Path_Exists("/sbin/mke2fs")) { + char command[512]; + + ui_print("Formatting %s using mke2fs...\n", Display_Name.c_str()); + Find_Actual_Block_Device(); + sprintf(command, "mke2fs -t %s -m 0 %s", Current_File_System.c_str(), Actual_Block_Device.c_str()); + LOGI("mke2fs command: %s\n", command); + if (__system(command) == 0) { + ui_print("Done.\n"); + return true; + } else { + LOGE("Unable to wipe '%s'.\n", Mount_Point.c_str()); + return false; + } + } else + return Wipe_RMRF(); + + return false; } bool TWPartition::Wipe_EXT4() { - LOGI("STUB TWPartition::Wipe_EXT4\n"); - return 1; + if (!UnMount(true)) + return false; + + if (Path_Exists("/sbin/make_ext4fs")) { + string Command; + + ui_print("Formatting %s using make_ext4fs...\n", Display_Name.c_str()); + Find_Actual_Block_Device(); + Command = "make_ext4fs"; + if (!Is_Decrypted && Length != 0) { + // Only use length if we're not decrypted + char len[32]; + sprintf(len, "%i", Length); + Command += " -l "; + Command += len; + } + Command += " " + Actual_Block_Device; + LOGI("make_ext4fs command: %s\n", Command.c_str()); + if (__system(Command.c_str()) == 0) { + ui_print("Done.\n"); + return true; + } else { + LOGE("Unable to wipe '%s'.\n", Mount_Point.c_str()); + return false; + } + } else + return Wipe_EXT23(); + + return false; } bool TWPartition::Wipe_FAT() { - LOGI("STUB TWPartition::Wipe_FAT\n"); - return 1; + char command[512]; + + if (Backup_Name == "and-sec") // Don't format if it's android secure + return Wipe_RMRF(); + + if (Path_Exists("/sbin/mkdosfs")) { + if (!UnMount(true)) + return false; + + ui_print("Formatting %s using mkdosfs...\n", Display_Name.c_str()); + Find_Actual_Block_Device(); + sprintf(command,"mkdosfs %s", Actual_Block_Device.c_str()); // use mkdosfs to format it + if (__system(command) == 0) { + ui_print("Done.\n"); + return true; + } else { + LOGE("Unable to wipe '%s'.\n", Mount_Point.c_str()); + return false; + } + return true; + } + else + return Wipe_RMRF(); + + return false; } -bool TWPartition::Wipe_YAFFS2() { - LOGI("STUB TWPartition::Wipe_YAFFS2\n"); - return 1; +bool TWPartition::Wipe_MTD() { + if (!UnMount(true)) + return false; + + ui_print("MTD Formatting \"%s\"\n", MTD_Name.c_str()); + + mtd_scan_partitions(); + const MtdPartition* mtd = mtd_find_partition_by_name(MTD_Name.c_str()); + if (mtd == NULL) { + LOGE("No mtd partition named '%s'", MTD_Name.c_str()); + return false; + } + + MtdWriteContext* ctx = mtd_write_partition(mtd); + if (ctx == NULL) { + LOGE("Can't write '%s', failed to format.", MTD_Name.c_str()); + return false; + } + if (mtd_erase_blocks(ctx, -1) == -1) { + mtd_write_close(ctx); + LOGE("Failed to format '%s'", MTD_Name.c_str()); + return false; + } + if (mtd_write_close(ctx) != 0) { + LOGE("Failed to close '%s'", MTD_Name.c_str()); + return false; + } + ui_print("Done.\n"); + return true; } bool TWPartition::Wipe_RMRF() { - LOGI("STUB TWPartition::Wipe_RMRF\n"); - return 1; + char cmd[512]; + + if (!Mount(true)) + return false; + + if (Backup_Name == "and-sec") { + ui_print("Using rm -rf on .android_secure\n"); + sprintf(cmd, "rm -rf %s/.android_secure/* && rm -rf %s/.android_secure/.*", Mount_Point.c_str(), Mount_Point.c_str()); + } else { + ui_print("Using rm -rf on '%s'\n", Mount_Point.c_str()); + sprintf(cmd, "rm -rf %s/* && rm -rf %s/.*", Mount_Point.c_str(), Mount_Point.c_str()); + } + + LOGI("rm -rf command is: '%s'\n", cmd); + __system(cmd); + return true; } bool TWPartition::Wipe_Data_Without_Wiping_Media() { - LOGI("STUB TWPartition::Wipe_Data_Without_Wiping_Media\n"); - return 1; + char cmd[256]; + + // This handles wiping data on devices with "sdcard" in /data/media + if (!Mount(true)) + return false; + + ui_print("Wiping data without wiping /data/media ...\n"); + __system("rm -f /data/*"); + __system("rm -f /data/.*"); + + DIR* d; + d = opendir("/data"); + if (d != NULL) + { + struct dirent* de; + while ((de = readdir(d)) != NULL) { + if (strcmp(de->d_name, "media") == 0) continue; + + sprintf(cmd, "rm -fr /data/%s", de->d_name); + __system(cmd); + } + closedir(d); + } + ui_print("Done.\n"); + return true; } bool TWPartition::Backup_Tar(string backup_folder) { @@ -820,6 +1040,7 @@ bool TWPartition::Restore_DD(string restore_folder) { bool TWPartition::Restore_Flash_Image(string restore_folder) { LOGI("STUB TWPartition::Restore_Flash_Image, backup_folder: '%s'\n", restore_folder.c_str()); + // might erase image first just to ensure that it flashes return 1; } @@ -829,7 +1050,10 @@ bool TWPartition::Update_Size(bool Display_Error) { if (!Can_Be_Mounted) return false; - if (!Mount(Display_Error)) + if (Removable || Is_Encrypted) { + if (!Mount(false)) + return true; + } else if (!Mount(Display_Error)) return false; ret = Get_Size_Via_statfs(Display_Error); @@ -854,3 +1078,34 @@ bool TWPartition::Update_Size(bool Display_Error) { } return true; } + +void TWPartition::Find_Actual_Block_Device(void) { + if (Is_Decrypted) { + Actual_Block_Device = Decrypted_Block_Device; + if (Path_Exists(Primary_Block_Device)) + Is_Present = true; + } else if (Path_Exists(Primary_Block_Device)) { + Is_Present = true; + Actual_Block_Device = Primary_Block_Device; + } else if (!Alternate_Block_Device.empty() && Path_Exists(Alternate_Block_Device)) { + Flip_Block_Device(); + Actual_Block_Device = Primary_Block_Device; + Is_Present = true; + } else + Is_Present = false; +} + +void TWPartition::Recreate_Media_Folder(void) { + string Command; + + if (!Mount(true)) { + LOGE("Unable to recreate /data/media folder.\n"); + } else { + LOGI("Recreating /data/media folder.\n"); + __system("cd /data && mkdir media && chmod 755 media"); + Command = "umount " + Symlink_Mount_Point; + __system(Command.c_str()); + Command = "mount " + Symlink_Path + " " + Symlink_Mount_Point; + __system(Command.c_str()); + } +} \ No newline at end of file diff --git a/partitionmanager.cpp b/partitionmanager.cpp index 21752a0cb..7ff5e8e05 100644 --- a/partitionmanager.cpp +++ b/partitionmanager.cpp @@ -34,6 +34,12 @@ #include "common.h" #include "partitions.hpp" #include "data.hpp" +#include "twrp-functions.hpp" + +extern "C" { + #include "extra-functions.h" + int __system(const char *command); +} #ifdef TW_INCLUDE_CRYPTO #ifdef TW_INCLUDE_JB_CRYPTO @@ -89,10 +95,7 @@ int TWPartitionManager::Write_Fstab(void) { } for (iter = Partitions.begin(); iter != Partitions.end(); iter++) { if ((*iter)->Can_Be_Mounted) { - if ((*iter)->Is_Decrypted) - Line = (*iter)->Decrypted_Block_Device + " " + (*iter)->Mount_Point + " " + (*iter)->Current_File_System + " rw\n"; - else - Line = (*iter)->Block_Device + " " + (*iter)->Mount_Point + " " + (*iter)->Current_File_System + " rw\n"; + Line = (*iter)->Actual_Block_Device + " " + (*iter)->Mount_Point + " " + (*iter)->Current_File_System + " rw\n"; fputs(Line.c_str(), fp); // Handle subpartition tracking if ((*iter)->Is_SubPartition) { @@ -112,7 +115,7 @@ int TWPartitionManager::Mount_By_Path(string Path, bool Display_Error) { std::vector::iterator iter; int ret = false; bool found = false; - string Local_Path = Get_Root_Path(Path); + string Local_Path = TWFunc::Get_Root_Path(Path); // Iterate through all partitions for (iter = Partitions.begin(); iter != Partitions.end(); iter++) { @@ -181,7 +184,7 @@ int TWPartitionManager::UnMount_By_Path(string Path, bool Display_Error) { std::vector::iterator iter; int ret = false; bool found = false; - string Local_Path = Get_Root_Path(Path); + string Local_Path = TWFunc::Get_Root_Path(Path); // Iterate through all partitions for (iter = Partitions.begin(); iter != Partitions.end(); iter++) { @@ -294,7 +297,7 @@ int TWPartitionManager::Mount_Settings_Storage(bool Display_Error) { TWPartition* TWPartitionManager::Find_Partition_By_Path(string Path) { std::vector::iterator iter; - string Local_Path = Get_Root_Path(Path); + string Local_Path = TWFunc::Get_Root_Path(Path); for (iter = Partitions.begin(); iter != Partitions.end(); iter++) { if ((*iter)->Mount_Point == Local_Path || (!(*iter)->Symlink_Mount_Point.empty() && (*iter)->Symlink_Mount_Point == Local_Path)) @@ -307,7 +310,7 @@ TWPartition* TWPartitionManager::Find_Partition_By_Block(string Block) { std::vector::iterator iter; for (iter = Partitions.begin(); iter != Partitions.end(); iter++) { - if ((*iter)->Block_Device == Block || (*iter)->Alternate_Block_Device == Block || ((*iter)->Is_Decrypted && (*iter)->Decrypted_Block_Device == Block)) + if ((*iter)->Primary_Block_Device == Block || (*iter)->Alternate_Block_Device == Block || ((*iter)->Is_Decrypted && (*iter)->Decrypted_Block_Device == Block)) return (*iter); } return NULL; @@ -331,7 +334,7 @@ int TWPartitionManager::Run_Backup(string Backup_Name) { int TWPartitionManager::Run_Restore(string Restore_Name) { int check; TWPartition* Part; - +LOGE("TO DO: Check MD5 of all partitions before restoring ANY partitions.\n"); DataManager::GetValue(TW_RESTORE_SYSTEM_VAR, check); if (check > 0) { Part = Find_Partition_By_Path("/system"); @@ -389,7 +392,7 @@ int TWPartitionManager::Run_Restore(string Restore_Name) { #ifdef SP1_NAME DataManager::GetValue(TW_RESTORE_SP1_VAR, check); if (check > 0) { - Part = Find_Partition_By_Path(Get_Root_Path(SP1_NAME)); + Part = Find_Partition_By_Path(TWFunc::Get_Root_Path(SP1_NAME)); if (Part) { if (!Part->Restore(Restore_Name)) return false; @@ -400,7 +403,7 @@ int TWPartitionManager::Run_Restore(string Restore_Name) { #ifdef SP2_NAME DataManager::GetValue(TW_RESTORE_SP2_VAR, check); if (check > 0) { - Part = Find_Partition_By_Path(Get_Root_Path(SP2_NAME)); + Part = Find_Partition_By_Path(TWFunc::Get_Root_Path(SP2_NAME)); if (Part) { if (!Part->Restore(Restore_Name)) return false; @@ -411,7 +414,7 @@ int TWPartitionManager::Run_Restore(string Restore_Name) { #ifdef SP3_NAME DataManager::GetValue(TW_RESTORE_SP3_VAR, check); if (check > 0) { - Part = Find_Partition_By_Path(Get_Root_Path(SP3_NAME)); + Part = Find_Partition_By_Path(TWFunc::Get_Root_Path(SP3_NAME)); if (Part) { if (!Part->Restore(Restore_Name)) return false; @@ -518,15 +521,15 @@ void TWPartitionManager::Set_Restore_Files(string Restore_Name) { if (Part->Mount_Point == "/sd-ext") tw_restore_sdext = 1; #ifdef SP1_NAME - if (Part->Mount_Point == Get_Root_Path(SP1_Name)) + if (Part->Mount_Point == TWFunc::Get_Root_Path(SP1_Name)) tw_restore_sp1 = 1; #endif #ifdef SP2_NAME - if (Part->Mount_Point == Get_Root_Path(SP2_Name)) + if (Part->Mount_Point == TWFunc::Get_Root_Path(SP2_Name)) tw_restore_sp2 = 1; #endif #ifdef SP3_NAME - if (Part->Mount_Point == Get_Root_Path(SP3_Name)) + if (Part->Mount_Point == TWFunc::Get_Root_Path(SP3_Name)) tw_restore_sp3 = 1; #endif } @@ -551,7 +554,7 @@ int TWPartitionManager::Wipe_By_Path(string Path) { std::vector::iterator iter; int ret = false; bool found = false; - string Local_Path = Get_Root_Path(Path); + string Local_Path = TWFunc::Get_Root_Path(Path); // Iterate through all partitions for (iter = Partitions.begin(); iter != Partitions.end(); iter++) { @@ -612,7 +615,7 @@ int TWPartitionManager::Factory_Reset(void) { int ret = true; for (iter = Partitions.begin(); iter != Partitions.end(); iter++) { - if ((*iter)->Wipe_During_Factory_Reset) { + if ((*iter)->Wipe_During_Factory_Reset && (*iter)->Is_Present) { if (!(*iter)->Wipe()) ret = false; } @@ -620,6 +623,101 @@ int TWPartitionManager::Factory_Reset(void) { return ret; } +int TWPartitionManager::Wipe_Dalvik_Cache(void) { + struct stat st; + + if (!Mount_By_Path("/data", true)) + return false; + + if (!Mount_By_Path("/cache", true)) + return false; + + ui_print("\nWiping Dalvik Cache Directories...\n"); + __system("rm -rf /data/dalvik-cache"); + ui_print("Cleaned: /data/dalvik-cache...\n"); + __system("rm -rf /cache/dalvik-cache"); + ui_print("Cleaned: /cache/dalvik-cache...\n"); + __system("rm -rf /cache/dc"); + ui_print("Cleaned: /cache/dc\n"); + + TWPartition* sdext = Find_Partition_By_Path("/sd-ext"); + if (sdext != NULL) { + if (sdext->Is_Present && sdext->Mount(false)) { + if (stat("/sd-ext/dalvik-cache", &st) == 0) { + __system("rm -rf /sd-ext/dalvik-cache"); + ui_print("Cleaned: /sd-ext/dalvik-cache...\n"); + } + } + } + ui_print("-- Dalvik Cache Directories Wipe Complete!\n\n"); + return true; +} + +int TWPartitionManager::Wipe_Rotate_Data(void) { + if (!Mount_By_Path("/data", true)) + return false; + + __system("rm -r /data/misc/akmd*"); + __system("rm -r /data/misc/rild*"); + ui_print("Rotation data wiped.\n"); + return true; +} + +int TWPartitionManager::Wipe_Battery_Stats(void) { + struct stat st; + + if (!Mount_By_Path("/data", true)) + return false; + + if (0 != stat("/data/system/batterystats.bin", &st)) { + ui_print("No Battery Stats Found. No Need To Wipe.\n"); + } else { + remove("/data/system/batterystats.bin"); + ui_print("Cleared battery stats.\n"); + } + return true; +} + +int TWPartitionManager::Format_Data(void) { + TWPartition* dat = Find_Partition_By_Path("/data"); + + if (dat != NULL) { + if (!dat->UnMount(true)) + return false; + + return dat->Wipe_Encryption(); + } else { + LOGE("Unable to locate /data.\n"); + return false; + } + return false; +} + +int TWPartitionManager::Wipe_Media_From_Data(void) { + TWPartition* dat = Find_Partition_By_Path("/data"); + + if (dat != NULL) { + if (!dat->Has_Data_Media) { + LOGE("This device does not have /data/media\n"); + return false; + } + if (!dat->Mount(true)) + return false; + + ui_print("Wiping internal storage -- /data/media...\n"); + __system("rm -rf /data/media"); + __system("cd /data && mkdir media && chmod 775 media"); + if (dat->Has_Data_Media) { + dat->Recreate_Media_Folder(); + } + return true; + } else { + LOGE("Unable to locate /data.\n"); + return false; + } + return false; +} + void TWPartitionManager::Refresh_Sizes(void) { Update_System_Details(); return; @@ -692,7 +790,7 @@ int TWPartitionManager::Decrypt_Device(string Password) { } else { TWPartition* dat = Find_Partition_By_Path("/data"); if (dat != NULL) { - DataManager::SetValue(TW_DATA_BLK_DEVICE, dat->Block_Device); + DataManager::SetValue(TW_DATA_BLK_DEVICE, dat->Primary_Block_Device); DataManager::SetValue(TW_IS_DECRYPTED, 1); dat->Is_Decrypted = true; dat->Decrypted_Block_Device = crypto_blkdev; @@ -711,17 +809,15 @@ int TWPartitionManager::Decrypt_Device(string Password) { return 1; } -string TWPartitionManager::Get_Root_Path(string Path) { - string Local_Path = Path; +int TWPartitionManager::Fix_Permissions(void) { + if (!Mount_By_Path("/data", true)) + return false; - // Make sure that we have a leading slash - if (Local_Path.substr(0, 1) != "/") - Local_Path = "/" + Local_Path; + if (!Mount_By_Path("/system", true)) + return false; - // Trim the path to get the root path only - size_t position = Local_Path.find("/", 2); - if (position != string::npos) { - Local_Path.resize(position); - } - return Local_Path; -} + ui_print("Fixing Permissions\nThis may take a few minutes.\n"); + __system("./sbin/fix_permissions.sh"); + ui_print("Done.\n\n"); + return true; +} \ No newline at end of file diff --git a/partitions.hpp b/partitions.hpp index 0609712cb..5b7dc6df9 100644 --- a/partitions.hpp +++ b/partitions.hpp @@ -57,9 +57,11 @@ public: virtual bool Wipe_Encryption(); // Ignores wipe commands for /data/media devices and formats the original block device virtual void Check_FS_Type(); // Checks the fs type using blkid, does not do anything on MTD / yaffs2 because this crashes on some devices virtual bool Update_Size(bool Display_Error); // Updates size information + virtual void Recreate_Media_Folder(); // Recreates the /data/media folder protected: bool Process_Fstab_Line(string Line, bool Display_Error); // Processes a fstab line + void Find_Actual_Block_Device(); // Determines the correct block device and stores it in Actual_Block_Device protected: bool Can_Be_Mounted; // Indicates that the partition can be mounted @@ -72,8 +74,10 @@ protected: string Symlink_Path; // Symlink path (e.g. /data/media) string Symlink_Mount_Point; // /sdcard could be the symlink mount point for /data/media string Mount_Point; // Mount point for this partition (e.g. /system or /data) - string Block_Device; // Block device (e.g. /dev/block/mmcblk1p1) + string Actual_Block_Device; // Actual block device (one of primary, alternate, or decrypted) + string Primary_Block_Device; // Block device (e.g. /dev/block/mmcblk1p1) string Alternate_Block_Device; // Alternate block device (e.g. /dev/block/mmcblk1) + string Decrypted_Block_Device; // Decrypted block device available after decryption bool Removable; // Indicates if this partition is removable -- affects how often we check overall size, if present, etc. bool Is_Present; // Indicates if the partition is currently present as a block device int Length; // Used by make_ext4fs to leave free space at the end of the partition block for things like a crypto footer @@ -84,10 +88,10 @@ protected: bool Can_Be_Encrypted; // This partition might be encrypted, affects error handling, can only be true if crypto support is compiled in bool Is_Encrypted; // This partition is thought to be encrypted -- it wouldn't mount for some reason, only avialble with crypto support bool Is_Decrypted; // This partition has successfully been decrypted - string Decrypted_Block_Device; // Decrypted block device available after decryption string Display_Name; // Display name for the GUI string Backup_Name; // Backup name -- used for backup filenames string Backup_FileName; // Actual backup filename + string MTD_Name; // Name of the partition for MTD devices Backup_Method_enum Backup_Method; // Method used for backup bool Has_Data_Media; // Indicates presence of /data/media, may affect wiping and backup methods bool Is_Storage; // Indicates if this partition is used for storage for backup, restore, and installing zips @@ -110,7 +114,7 @@ private: bool Wipe_EXT23(); // Formats as ext3 or ext2 bool Wipe_EXT4(); // Formats using ext4, uses make_ext4fs when present bool Wipe_FAT(); // Formats as FAT except that mkdosfs from busybox usually fails so oftentimes this is actually a rm -rf wipe - bool Wipe_YAFFS2(); // Formats as yaffs2 for MTD memory types + bool Wipe_MTD(); // Formats as yaffs2 for MTD memory types bool Wipe_RMRF(); // Uses rm -rf to wipe bool Wipe_Data_Without_Wiping_Media(); // Uses rm -rf to wipe but does not wipe /data/media bool Backup_Tar(string backup_folder); // Backs up using tar for file systems @@ -123,6 +127,7 @@ private: bool Get_Size_Via_df(bool Display_Error); // Get Partition size, used, and free space using df command unsigned long long Get_Folder_Size(string Path, bool Display_Error); // Gets the size of the files in a folder and all of its subfolders bool Make_Dir(string Path, bool Display_Error); // Creates a directory if it doesn't already exist + bool Find_MTD_Block_Device(string MTD_Name); // Finds the mtd block device based on the name from the fstab friend class TWPartitionManager; }; @@ -157,10 +162,15 @@ public: virtual int Wipe_By_Block(string Block); // Wipes a partition based on block device virtual int Wipe_By_Name(string Name); // Wipes a partition based on display name virtual int Factory_Reset(); // Performs a factory reset + virtual int Wipe_Dalvik_Cache(); // Wipes dalvik cache + virtual int Wipe_Rotate_Data(); // Wipes rotation data -- + virtual int Wipe_Battery_Stats(); // Wipe battery stats -- /data/system/batterystats.bin + virtual int Format_Data(); // Really formats data on /data/media devices -- also removes encryption + virtual int Wipe_Media_From_Data(); // Removes and recreates the media folder on /data/media devices virtual void Refresh_Sizes(); // Refreshes size data of partitions virtual void Update_System_Details(); // Updates fstab, file systems, sizes, etc. virtual int Decrypt_Device(string Password); // Attempt to decrypt any encrypted partitions - virtual string Get_Root_Path(string Path); // Trims any trailing folders or filenames from the path, also adds a leading / if not present + virtual int Fix_Permissions(); // Fixes permissions in /system and /data private: std::vector Partitions; // Vector list of all partitions diff --git a/prebuilt/Android.mk b/prebuilt/Android.mk index 8b0f5cf57..58268f992 100644 --- a/prebuilt/Android.mk +++ b/prebuilt/Android.mk @@ -53,6 +53,9 @@ endif ifeq ($(TW_INCLUDE_JB_CRYPTO), true) RELINK_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/libcrypto.so endif +ifeq ($(TARGET_USERIMAGES_USE_EXT4), true) + RELINK_SOURCE_FILES += $(TARGET_OUT_EXECUTABLES)/make_ext4fs +endif TWRP_AUTOGEN := $(intermediates)/teamwin diff --git a/reboot.c b/reboot.c index 0fbda8176..9d87ff21d 100644 --- a/reboot.c +++ b/reboot.c @@ -42,8 +42,6 @@ int tw_reboot(RebootCommand command) // Always force a sync before we reboot sync(); - ensure_path_unmounted("/sdcard"); - switch (command) { case rb_current: diff --git a/recovery.cpp b/recovery.cpp index 567a42e54..743920c85 100644 --- a/recovery.cpp +++ b/recovery.cpp @@ -32,7 +32,11 @@ #include "bootloader.h" #include "common.h" #include "cutils/properties.h" +#ifdef ANDROID_RB_RESTART #include "cutils/android_reboot.h" +#else +#include +#endif #include "install.h" #include "minui/minui.h" #include "minzip/DirUtil.h" @@ -929,6 +933,10 @@ main(int argc, char **argv) { // Otherwise, get ready to boot the main system... finish_recovery(send_intent); ui->Print("Rebooting...\n"); +#ifdef ANDROID_RB_RESTART android_reboot(ANDROID_RB_RESTART, 0, 0); +#else + reboot(RB_AUTOBOOT); +#endif return EXIT_SUCCESS; } diff --git a/roots.cpp b/roots.cpp index e74747378..69c98fc1d 100644 --- a/roots.cpp +++ b/roots.cpp @@ -274,7 +274,11 @@ int format_volume(const char* volume) { } if (strcmp(v->fs_type, "ext4") == 0) { +#ifdef USE_EXT4 int result = make_ext4fs(v->device, v->length, volume, sehandle); +#else + int result = 0; +#endif if (result != 0) { LOGE("format_volume: make_extf4fs failed on %s\n", v->device); return -1; diff --git a/twinstall.cpp b/twinstall.cpp index 0c3d8375c..967528e27 100644 --- a/twinstall.cpp +++ b/twinstall.cpp @@ -39,6 +39,7 @@ #include "variables.h" #include "data.hpp" #include "partitions.hpp" +#include "twrp-functions.hpp" extern "C" { #include "extra-functions.h" @@ -422,98 +423,6 @@ exit: return NULL; } -char* get_path (char* path) { - char *s; - - /* Go to the end of the string. */ - s = path + strlen(path) - 1; - - /* Strip off trailing /s (unless it is also the leading /). */ - while (path < s && s[0] == '/') - s--; - - /* Strip the last component. */ - while (path <= s && s[0] != '/') - s--; - - while (path < s && s[0] == '/') - s--; - - if (s < path) - return (char*)("."); - - s[1] = '\0'; - return path; -} - -/* - Checks md5 for a path - Return values: - -1 : MD5 does not exist - 0 : Failed - 1 : Success -*/ -int check_md5(const char* path) { - FILE* fp; - char command[255], line[512], actual_md5[512], md5[512]; - char md5file[PATH_MAX + 40]; - char *ptr; - unsigned int line_len, index = 0; - struct stat st; - - // Check to see if the filename.zip.md5 file exists - strcpy(md5file, path); - strcat(md5file, ".md5"); - if (stat(md5file, &st) != 0) - return -1; // no MD5 file found - - // Dump the md5 of the zip to a text file for reading - sprintf(command, "md5sum '%s' > /tmp/md5output.txt", path); - __system(command); - fp = fopen("/tmp/md5output.txt", "rt"); - if (fp == NULL) { - LOGI("Unable to open /tmp/md5output.txt.\n"); - return false; - } - - while (fgets(line, sizeof(line), fp) != NULL) - { - line_len = strlen(line); - for (index = 0; index < line_len; index++) { - if (line[index] <= 32) - line[index] = '\0'; - } - strcpy(actual_md5, line); - break; - } - fclose(fp); - - // Read the filename.zip.md5 file - fp = fopen(md5file, "rt"); - if (fp == NULL) { - LOGI("Unable to open '%s'.\n", md5file); - return false; - } - - while (fgets(line, sizeof(line), fp) != NULL) - { - line_len = strlen(line); - for (index = 0; index < line_len; index++) { - if (line[index] <= 32) - line[index] = '\0'; - } - strcpy(md5, line); - break; - } - fclose(fp); - - // Comare the 2 MD5 values - if (strcmp(actual_md5, md5) == 0) - return 1; - LOGI("MD5 did not match: '%s' != '%s'\n", actual_md5, md5); - return 0; -} - extern "C" int TWinstall_zip(const char* path, int* wipe_cache) { int err, zip_verify, md5_return, md5_verify; @@ -525,7 +434,7 @@ extern "C" int TWinstall_zip(const char* path, int* wipe_cache) { } ui_print("Checking for MD5 file...\n"); - md5_return = check_md5(path); + md5_return = TWFunc::Check_MD5(path); if (md5_return == 0) { // MD5 did not match. LOGE("Zip MD5 does not match.\nUnable to install zip.\n"); diff --git a/twrp-functions.cpp b/twrp-functions.cpp new file mode 100644 index 000000000..ccf0540a1 --- /dev/null +++ b/twrp-functions.cpp @@ -0,0 +1,164 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "twrp-functions.hpp" +#include "partitions.hpp" +#include "common.h" +extern "C" { + #include "extra-functions.h" + int __system(const char *command); +} + +/* Checks md5 for a path + Return values: + -1 : MD5 does not exist + 0 : Failed + 1 : Success */ +int TWFunc::Check_MD5(string File) { + int ret; + string Command, DirPath, MD5_File, Sline, Filename, MD5_File_Filename, OK; + char line[255]; + size_t pos; + + MD5_File = File + ".md5"; + if (access(MD5_File.c_str(), F_OK ) != -1) { + DirPath = Get_Path(File); + chdir(DirPath.c_str()); + MD5_File = Get_Filename(MD5_File); + Command = "/sbin/busybox md5sum -c '" + MD5_File + "' > /tmp/md5output"; + __system(Command.c_str()); + FILE * cs = fopen("/tmp/md5output", "r"); + if (cs == NULL) { + LOGE("Unable to open md5 output file.\n"); + return 0; + } + + fgets(line, sizeof(line), cs); + + Sline = line; + pos = Sline.find(":"); + if (pos != string::npos) { + Filename = Get_Filename(File); + MD5_File_Filename = Sline.substr(0, pos); + OK = Sline.substr(pos + 2, Sline.size() - pos - 2); + if (Filename == MD5_File_Filename && (OK == "OK" || OK == "OK\n")) { + //MD5 is good, return 1 + ret = 1; + } else { + // MD5 is bad, return 0 + ret = 0; + } + } else { + // MD5 is bad, return 0 + ret = 0; + } + fclose(cs); + } else { + //No md5 file, return -1 + ret = -1; + } + + return ret; +} + +// Returns "file.name" from a full /path/to/file.name +string TWFunc::Get_Filename(string Path) { + size_t pos = Path.find_last_of("/"); + if (pos != string::npos) { + string Filename; + Filename = Path.substr(pos + 1, Path.size() - pos - 1); + return Filename; + } else + return Path; +} + +// Returns "/path/to/" from a full /path/to/file.name +string TWFunc::Get_Path(string Path) { + size_t pos = Path.find_last_of("/"); + if (pos != string::npos) { + string Pathonly; + Pathonly = Path.substr(0, pos + 1); + return Pathonly; + } else + return Path; +} + +// Returns "/path" from a full /path/to/file.name +string TWFunc::Get_Root_Path(string Path) { + string Local_Path = Path; + + // Make sure that we have a leading slash + if (Local_Path.substr(0, 1) != "/") + Local_Path = "/" + Local_Path; + + // Trim the path to get the root path only + size_t position = Local_Path.find("/", 2); + if (position != string::npos) { + Local_Path.resize(position); + } + return Local_Path; +} + +void TWFunc::install_htc_dumlock(void) { + struct statfs fs1, fs2; + int need_libs = 0; + + if (!PartitionManager.Mount_By_Path("/system", true)) + return; + + if (!PartitionManager.Mount_By_Path("/data", true)) + return; + + ui_print("Installing HTC Dumlock to system...\n"); + __system("cp /res/htcd/htcdumlocksys /system/bin/htcdumlock && chmod 755 /system/bin/htcdumlock"); + if (statfs("/system/bin/flash_image", &fs1) != 0) { + ui_print("Installing flash_image...\n"); + __system("cp /res/htcd/flash_imagesys /system/bin/flash_image && chmod 755 /system/bin/flash_image"); + need_libs = 1; + } else + ui_print("flash_image is already installed, skipping...\n"); + if (statfs("/system/bin/dump_image", &fs2) != 0) { + ui_print("Installing dump_image...\n"); + __system("cp /res/htcd/dump_imagesys /system/bin/dump_image && chmod 755 /system/bin/dump_image"); + need_libs = 1; + } else + ui_print("dump_image is already installed, skipping...\n"); + if (need_libs) { + ui_print("Installing libs needed for flash_image and dump_image...\n"); + __system("cp /res/htcd/libbmlutils.so /system/lib && chmod 755 /system/lib/libbmlutils.so"); + __system("cp /res/htcd/libflashutils.so /system/lib && chmod 755 /system/lib/libflashutils.so"); + __system("cp /res/htcd/libmmcutils.so /system/lib && chmod 755 /system/lib/libmmcutils.so"); + __system("cp /res/htcd/libmtdutils.so /system/lib && chmod 755 /system/lib/libmtdutils.so"); + } + ui_print("Installing HTC Dumlock app...\n"); + mkdir("/data/app", 0777); + __system("rm /data/app/com.teamwin.htcdumlock*"); + __system("cp /res/htcd/HTCDumlock.apk /data/app/com.teamwin.htcdumlock.apk"); + sync(); + ui_print("HTC Dumlock is installed.\n"); +} + +void TWFunc::htc_dumlock_restore_original_boot(void) { + if (!PartitionManager.Mount_By_Path("/sdcard", true)) + return; + + ui_print("Restoring original boot...\n"); + __system("htcdumlock restore"); + ui_print("Original boot restored.\n"); +} + +void TWFunc::htc_dumlock_reflash_recovery_to_boot(void) { + if (!PartitionManager.Mount_By_Path("/sdcard", true)) + return; + + ui_print("Reflashing recovery to boot...\n"); + __system("htcdumlock recovery noreboot"); + ui_print("Recovery is flashed to boot.\n"); +} diff --git a/twrp-functions.hpp b/twrp-functions.hpp new file mode 100644 index 000000000..19f8eec66 --- /dev/null +++ b/twrp-functions.hpp @@ -0,0 +1,23 @@ +#ifndef _TWRPFUNCTIONS_HPP +#define _TWRPFUNCTIONS_HPP + +#include + +using namespace std; + +// Partition class +class TWFunc +{ +public: + static int Check_MD5(string File); + static string Get_Root_Path(string Path); // Trims any trailing folders or filenames from the path, also adds a leading / if not present + static string Get_Path(string Path); // Trims everything after the last / in the string + static string Get_Filename(string Path); // Trims the path off of a filename + + static void install_htc_dumlock(void); // Installs HTC Dumlock + static void htc_dumlock_restore_original_boot(void); // Restores the backup of boot from HTC Dumlock + static void htc_dumlock_reflash_recovery_to_boot(void); // Reflashes the current recovery to boot + +}; + +#endif // _TWRPFUNCTIONS_HPP diff --git a/ui.cpp b/ui.cpp index bd0fcae62..27ecc2805 100644 --- a/ui.cpp +++ b/ui.cpp @@ -28,7 +28,9 @@ #include #include +#ifdef ANDROID_RB_RESTART #include +#endif #include "common.h" #include "device.h" @@ -131,7 +133,9 @@ void RecoveryUI::process_key(int key_code, int updown) { break; case RecoveryUI::REBOOT: +#ifdef ANDROID_RB_RESTART android_reboot(ANDROID_RB_RESTART, 0, 0); +#endif break; case RecoveryUI::ENQUEUE: -- cgit v1.2.3