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
diff --git a/Android.mk b/Android.mk
index 6d3be1d..6c6ee9b 100644
--- a/Android.mk
+++ b/Android.mk
@@ -38,7 +38,8 @@
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 8b717f5..896bb1b 100644
--- a/data.cpp
+++ b/data.cpp
@@ -50,8 +50,6 @@
void gui_notifyVarChange(const char *name, const char* value);
- int get_battery_level(void);
-
int __system(const char *command);
}
@@ -761,8 +759,36 @@
if (varName == "tw_battery")
{
char tmp[16];
+ static char charging = ' ';
+ static int lastVal = -1;
+ static time_t nextSecCheck = 0;
- sprintf(tmp, "%i%%", get_battery_level());
+ 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%%%c", lastVal, charging);
value = tmp;
return 0;
}
diff --git a/extra-functions.c b/extra-functions.c
index e01ab83..952c091 100644
--- a/extra-functions.c
+++ b/extra-functions.c
@@ -339,102 +339,6 @@
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 @@
//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 6145e77..664ca33 100644
--- a/extra-functions.h
+++ b/extra-functions.h
@@ -8,22 +8,12 @@
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 a1f7dd3..b050feb 100644
--- a/gui/action.cpp
+++ b/gui/action.cpp
@@ -19,6 +19,7 @@
#include <string>
#include <sstream>
#include "../partitions.hpp"
+#include "../twrp-functions.hpp"
extern "C" {
#include "../common.h"
@@ -31,7 +32,6 @@
#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 @@
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");
- } else
- PartitionManager.Wipe_By_Path(arg);
+ string External_Path;
- if (arg == "/sdcard") {
- PartitionManager.Mount_By_Path("/sdcard", 1);
- mkdir("/sdcard/TWRP", 0777);
- DataManager::Flush();
+ DataManager::GetValue(TW_EXTERNAL_PATH, External_Path);
+ ret_val = PartitionManager.Wipe_By_Path(External_Path);
+ } else
+ ret_val = PartitionManager.Wipe_By_Path(arg);
+
+ 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 @@
if (simulate) {
simulate_progress_bar();
} else
- fix_perms();
+ PartitionManager.Fix_Permissions();
LOGI("fix permissions DONE!\n");
operation_end(0, simulate);
@@ -870,7 +865,7 @@
if (simulate) {
simulate_progress_bar();
} else
- install_htc_dumlock();
+ TWFunc::install_htc_dumlock();
operation_end(0, simulate);
return 0;
@@ -881,7 +876,7 @@
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 @@
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 f3c79f7..f4fa0d8 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 @@
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 @@
Display_Name = "";
Backup_Name = "";
Backup_FileName = "";
+ MTD_Name = "";
Backup_Method = NONE;
Has_Data_Media = false;
Is_Storage = false;
@@ -109,15 +113,19 @@
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 @@
// 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 @@
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 @@
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 @@
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 @@
} 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 @@
} 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 @@
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_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 @@
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 @@
}
}
+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 @@
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 @@
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 @@
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 @@
} 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;
+
+ 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 (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;
- }
- }
- if (Removable)
- Update_Size(Display_Error);
return true;
}
@@ -650,6 +670,9 @@
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::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 @@
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 @@
}
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_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 @@
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 @@
}
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 21752a0..7ff5e8e 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 @@
}
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 @@
std::vector<TWPartition*>::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 @@
std::vector<TWPartition*>::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 @@
TWPartition* TWPartitionManager::Find_Partition_By_Path(string Path) {
std::vector<TWPartition*>::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 @@
std::vector<TWPartition*>::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_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 @@
#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 @@
#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 @@
#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 @@
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 @@
std::vector<TWPartition*>::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 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 @@
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 @@
} 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 @@
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 0609712..5b7dc6d 100644
--- a/partitions.hpp
+++ b/partitions.hpp
@@ -57,9 +57,11 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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<TWPartition*> Partitions; // Vector list of all partitions
diff --git a/prebuilt/Android.mk b/prebuilt/Android.mk
index 8b0f5cf..58268f9 100644
--- a/prebuilt/Android.mk
+++ b/prebuilt/Android.mk
@@ -53,6 +53,9 @@
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 0fbda81..9d87ff2 100644
--- a/reboot.c
+++ b/reboot.c
@@ -42,8 +42,6 @@
// 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 567a42e..743920c 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 <sys/reboot.h>
+#endif
#include "install.h"
#include "minui/minui.h"
#include "minzip/DirUtil.h"
@@ -929,6 +933,10 @@
// 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 e747473..69c98fc 100644
--- a/roots.cpp
+++ b/roots.cpp
@@ -274,7 +274,11 @@
}
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 0c3d837..967528e 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 @@
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 @@
}
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 0000000..ccf0540
--- /dev/null
+++ b/twrp-functions.cpp
@@ -0,0 +1,164 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/vfs.h>
+#include <unistd.h>
+#include <vector>
+#include <dirent.h>
+#include <time.h>
+
+#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 0000000..19f8eec
--- /dev/null
+++ b/twrp-functions.hpp
@@ -0,0 +1,23 @@
+#ifndef _TWRPFUNCTIONS_HPP
+#define _TWRPFUNCTIONS_HPP
+
+#include <string>
+
+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 bd0fcae..27ecc28 100644
--- a/ui.cpp
+++ b/ui.cpp
@@ -28,7 +28,9 @@
#include <time.h>
#include <unistd.h>
+#ifdef ANDROID_RB_RESTART
#include <cutils/android_reboot.h>
+#endif
#include "common.h"
#include "device.h"
@@ -131,7 +133,9 @@
break;
case RecoveryUI::REBOOT:
+#ifdef ANDROID_RB_RESTART
android_reboot(ANDROID_RB_RESTART, 0, 0);
+#endif
break;
case RecoveryUI::ENQUEUE: