diff options
Diffstat (limited to 'partition.cpp')
-rw-r--r-- | partition.cpp | 269 |
1 files changed, 168 insertions, 101 deletions
diff --git a/partition.cpp b/partition.cpp index 1261a2a26..bf87de38a 100644 --- a/partition.cpp +++ b/partition.cpp @@ -25,6 +25,7 @@ #include <unistd.h> #include <dirent.h> #include <libgen.h> +#include <zlib.h> #include <iostream> #include <sstream> #include <sys/param.h> @@ -46,6 +47,7 @@ #include "infomanager.hpp" #include "set_metadata.h" #include "gui/gui.hpp" +#include "adbbu/libtwadbbu.hpp" extern "C" { #include "mtdutils/mtdutils.h" #include "mtdutils/mounts.h" @@ -208,7 +210,7 @@ TWPartition::TWPartition() { Backup_Name = ""; Backup_FileName = ""; MTD_Name = ""; - Backup_Method = NONE; + Backup_Method = BM_NONE; Can_Encrypt_Backup = false; Use_Userdata_Encryption = false; Has_Data_Media = false; @@ -801,16 +803,16 @@ void TWPartition::Setup_File_System(bool Display_Error) { Make_Dir(Mount_Point, Display_Error); Display_Name = Mount_Point.substr(1, Mount_Point.size() - 1); Backup_Name = Display_Name; - Backup_Method = FILES; + Backup_Method = BM_FILES; } void TWPartition::Setup_Image(bool Display_Error) { Display_Name = Mount_Point.substr(1, Mount_Point.size() - 1); Backup_Name = Display_Name; if (Current_File_System == "emmc") - Backup_Method = DD; + Backup_Method = BM_DD; else if (Current_File_System == "mtd" || Current_File_System == "bml") - Backup_Method = FLASH_UTILS; + Backup_Method = BM_FLASH_UTILS; else LOGINFO("Unhandled file system '%s' on image '%s'\n", Current_File_System.c_str(), Display_Name.c_str()); if (Find_Partition_Size()) { @@ -1598,14 +1600,13 @@ bool TWPartition::Resize() { return false; } -bool TWPartition::Backup(const string& backup_folder, pid_t &tar_fork_pid, ProgressTracking *progress) { - if (Backup_Method == FILES) { - return Backup_Tar(backup_folder, progress, tar_fork_pid); - } - else if (Backup_Method == DD) - return Backup_Image(backup_folder, progress); - else if (Backup_Method == FLASH_UTILS) - return Backup_Dump_Image(backup_folder, progress); +bool TWPartition::Backup(PartitionSettings *part_settings, pid_t *tar_fork_pid) { + if (Backup_Method == BM_FILES) + return Backup_Tar(part_settings, tar_fork_pid); + else if (Backup_Method == BM_DD) + return Backup_Image(part_settings); + else if (Backup_Method == BM_FLASH_UTILS) + return Backup_Dump_Image(part_settings); LOGERR("Unknown backup method for '%s'\n", Mount_Point.c_str()); return false; } @@ -1658,53 +1659,49 @@ bool TWPartition::Check_MD5(string restore_folder) { return false; } -bool TWPartition::Restore(const string& restore_folder, ProgressTracking *progress) { - string Restore_File_System; - +bool TWPartition::Restore(PartitionSettings *part_settings) { TWFunc::GUI_Operation_Text(TW_RESTORE_TEXT, Display_Name, gui_parse_text("{@restoring_hdr}")); - LOGINFO("Restore filename is: %s\n", Backup_FileName.c_str()); + LOGINFO("Restore filename is: %s/%s\n", part_settings->Restore_Name.c_str(), part_settings->Backup_FileName.c_str()); - Restore_File_System = Get_Restore_File_System(restore_folder); + string Restore_File_System = Get_Restore_File_System(part_settings); if (Is_File_System(Restore_File_System)) - return Restore_Tar(restore_folder, Restore_File_System, progress); - else if (Is_Image(Restore_File_System)) { - return Restore_Image(restore_folder, Restore_File_System, progress); - } + return Restore_Tar(part_settings); + else if (Is_Image(Restore_File_System)) + return Restore_Image(part_settings); LOGERR("Unknown restore method for '%s'\n", Mount_Point.c_str()); return false; } -string TWPartition::Get_Restore_File_System(const string& restore_folder) { +string TWPartition::Get_Restore_File_System(PartitionSettings *part_settings) { size_t first_period, second_period; string Restore_File_System; // Parse backup filename to extract the file system before wiping - first_period = Backup_FileName.find("."); + first_period = part_settings->Backup_FileName.find("."); if (first_period == string::npos) { LOGERR("Unable to find file system (first period).\n"); return string(); } - Restore_File_System = Backup_FileName.substr(first_period + 1, Backup_FileName.size() - first_period - 1); + Restore_File_System = part_settings->Backup_FileName.substr(first_period + 1, part_settings->Backup_FileName.size() - first_period - 1); second_period = Restore_File_System.find("."); if (second_period == string::npos) { LOGERR("Unable to find file system (second period).\n"); return string(); } Restore_File_System.resize(second_period); - LOGINFO("Restore file system is: '%s'.\n", Restore_File_System.c_str()); return Restore_File_System; } string TWPartition::Backup_Method_By_Name() { - if (Backup_Method == NONE) + if (Backup_Method == BM_NONE) return "none"; - else if (Backup_Method == FILES) + else if (Backup_Method == BM_FILES) return "files"; - else if (Backup_Method == DD) + else if (Backup_Method == BM_DD) return "dd"; - else if (Backup_Method == FLASH_UTILS) + else if (Backup_Method == BM_FLASH_UTILS) return "flash_utils"; else return "undefined"; @@ -2141,7 +2138,7 @@ bool TWPartition::Wipe_Data_Without_Wiping_Media_Func(const string& parent __unu return false; } -bool TWPartition::Backup_Tar(const string& backup_folder, ProgressTracking *progress, pid_t &tar_fork_pid) { +bool TWPartition::Backup_Tar(PartitionSettings *part_settings, pid_t *tar_fork_pid) { string Full_FileName; twrpTar tar; @@ -2169,72 +2166,114 @@ bool TWPartition::Backup_Tar(const string& backup_folder, ProgressTracking *prog #endif Backup_FileName = Backup_Name + "." + Current_File_System + ".win"; - Full_FileName = backup_folder + "/" + Backup_FileName; + Full_FileName = part_settings->Full_Backup_Path + Backup_FileName; tar.has_data_media = Has_Data_Media; - Full_FileName = backup_folder + "/" + Backup_FileName; + tar.part_settings = part_settings; tar.setdir(Backup_Path); tar.setfn(Full_FileName); tar.setsize(Backup_Size); tar.partition_name = Backup_Name; - tar.backup_folder = backup_folder; - if (tar.createTarFork(progress, tar_fork_pid) != 0) + tar.backup_folder = part_settings->Full_Backup_Path; + if (tar.createTarFork(tar_fork_pid) != 0) return false; return true; } -bool TWPartition::Backup_Image(const string& backup_folder, ProgressTracking *progress) { - string Full_FileName; +bool TWPartition::Backup_Image(PartitionSettings *part_settings) { + string Full_FileName, adb_file_name; + int adb_control_bu_fd, compressed; TWFunc::GUI_Operation_Text(TW_BACKUP_TEXT, Display_Name, gui_parse_text("{@backing}")); gui_msg(Msg("backing_up=Backing up {1}...")(Backup_Display_Name)); Backup_FileName = Backup_Name + "." + Current_File_System + ".win"; - Full_FileName = backup_folder + "/" + Backup_FileName; - if (!Raw_Read_Write(Actual_Block_Device, Full_FileName, Backup_Size, progress)) - return false; + if (part_settings->adbbackup) { + Full_FileName = TW_ADB_BACKUP; + adb_file_name = part_settings->Full_Backup_Path + "/" + Backup_FileName; + } + else + Full_FileName = part_settings->Full_Backup_Path + "/" + Backup_FileName; - tw_set_default_metadata(Full_FileName.c_str()); - if (TWFunc::Get_File_Size(Full_FileName) == 0) { - gui_msg(Msg(msg::kError, "backup_size=Backup file size for '{1}' is 0 bytes.")(Full_FileName)); + part_settings->total_restore_size = Backup_Size; + + if (part_settings->adbbackup) { + if (!twadbbu::Write_TWIMG(adb_file_name, Backup_Size)) + return false; + } + + if (!Raw_Read_Write(part_settings)) return false; + + if (part_settings->adbbackup) { + if (!twadbbu::Write_TWEOF()) + return false; } return true; } -bool TWPartition::Raw_Read_Write(const string& input_file, const string& output_file, const unsigned long long input_size, ProgressTracking *progress) { - unsigned long long RW_Block_Size, Remain; - int src_fd = -1, dest_fd = -1, bs; +bool TWPartition::Raw_Read_Write(PartitionSettings *part_settings) { + unsigned long long RW_Block_Size, Remain = Backup_Size; + int src_fd = -1, dest_fd = -1; + ssize_t bs; bool ret = false; void* buffer = NULL; unsigned long long backedup_size = 0; + string srcfn, destfn; - RW_Block_Size = 1048576LLU; // 1MB - Remain = input_size; + if (part_settings->PM_Method == PM_BACKUP) { + srcfn = Actual_Block_Device; + if (part_settings->adbbackup) + destfn = TW_ADB_BACKUP; + else + destfn = part_settings->Full_Backup_Path + part_settings->Backup_FileName; + } + else { + destfn = Actual_Block_Device; + if (part_settings->adbbackup) { + srcfn = TW_ADB_RESTORE; + } else { + srcfn = part_settings->Restore_Name + "/" + part_settings->Backup_FileName; + Remain = TWFunc::Get_File_Size(srcfn); + } + } - src_fd = open(input_file.c_str(), O_RDONLY | O_LARGEFILE); + src_fd = open(srcfn.c_str(), O_RDONLY | O_LARGEFILE); if (src_fd < 0) { - gui_msg(Msg(msg::kError, "error_opening_strerr=Error opening: '{1}' ({2})")(input_file)(strerror(errno))); + gui_msg(Msg(msg::kError, "error_opening_strerr=Error opening: '{1}' ({2})")(srcfn.c_str())(strerror(errno))); return false; } - dest_fd = open(output_file.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_LARGEFILE, S_IRUSR | S_IWUSR); + + dest_fd = open(destfn.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_LARGEFILE, S_IRUSR | S_IWUSR); if (dest_fd < 0) { - gui_msg(Msg(msg::kError, "error_opening_strerr=Error opening: '{1}' ({2})")(output_file)(strerror(errno))); + gui_msg(Msg(msg::kError, "error_opening_strerr=Error opening: '{1}' ({2})")(destfn.c_str())(strerror(errno))); goto exit; } - bs = (int)(RW_Block_Size); + + LOGINFO("Reading '%s', writing '%s'\n", srcfn.c_str(), destfn.c_str()); + + if (part_settings->adbbackup) { + RW_Block_Size = MAX_ADB_READ; + bs = MAX_ADB_READ; + } + else { + RW_Block_Size = 1048576LLU; // 1MB + bs = (ssize_t)(RW_Block_Size); + } + buffer = malloc((size_t)bs); if (!buffer) { LOGINFO("Raw_Read_Write failed to malloc\n"); goto exit; } - LOGINFO("Reading '%s', writing '%s'\n", input_file.c_str(), output_file.c_str()); - if (progress) - progress->SetPartitionSize(input_size); + + if (part_settings->progress) + part_settings->progress->SetPartitionSize(part_settings->total_restore_size); + while (Remain > 0) { if (Remain < RW_Block_Size) - bs = (int)(Remain); - if (read(src_fd, buffer, bs) != bs) { + bs = (ssize_t)(Remain); + if (read(src_fd, buffer, bs) != bs) { LOGINFO("Error reading source fd (%s)\n", strerror(errno)); goto exit; } @@ -2243,14 +2282,14 @@ bool TWPartition::Raw_Read_Write(const string& input_file, const string& output_ goto exit; } backedup_size += (unsigned long long)(bs); - Remain -= (unsigned long long)(bs); - if (progress) - progress->UpdateSize(backedup_size); + Remain = Remain - (unsigned long long)(bs); + if (part_settings->progress) + part_settings->progress->UpdateSize(backedup_size); if (PartitionManager.Check_Backup_Cancel() != 0) goto exit; } - if (progress) - progress->UpdateDisplayDetails(true); + if (part_settings->progress) + part_settings->progress->UpdateDisplayDetails(true); fsync(dest_fd); ret = true; exit: @@ -2263,19 +2302,22 @@ exit: return ret; } -bool TWPartition::Backup_Dump_Image(const string& backup_folder, ProgressTracking *progress) { +bool TWPartition::Backup_Dump_Image(PartitionSettings *part_settings) { string Full_FileName, Command; + int use_compression, adb_control_bu_fd; + unsigned long long compressed; TWFunc::GUI_Operation_Text(TW_BACKUP_TEXT, Display_Name, gui_parse_text("{@backing}")); gui_msg(Msg("backing_up=Backing up {1}...")(Backup_Display_Name)); - if (progress) - progress->SetPartitionSize(Backup_Size); + if (part_settings->progress) + part_settings->progress->SetPartitionSize(Backup_Size); Backup_FileName = Backup_Name + "." + Current_File_System + ".win"; - Full_FileName = backup_folder + "/" + Backup_FileName; + Full_FileName = part_settings->Full_Backup_Path + "/" + Backup_FileName; Command = "dump_image " + MTD_Name + " '" + Full_FileName + "'"; + LOGINFO("Backup command: '%s'\n", Command.c_str()); TWFunc::Exec_Cmd(Command); tw_set_default_metadata(Full_FileName.c_str()); @@ -2284,23 +2326,26 @@ bool TWPartition::Backup_Dump_Image(const string& backup_folder, ProgressTrackin gui_msg(Msg(msg::kError, "backup_size=Backup file size for '{1}' is 0 bytes.")(Full_FileName)); return false; } - if (progress) - progress->UpdateSize(Backup_Size); + if (part_settings->progress) + part_settings->progress->UpdateSize(Backup_Size); + return true; } -unsigned long long TWPartition::Get_Restore_Size(const string& restore_folder) { - InfoManager restore_info(restore_folder + "/" + Backup_Name + ".info"); - if (restore_info.LoadValues() == 0) { - if (restore_info.GetValue("backup_size", Restore_Size) == 0) { - LOGINFO("Read info file, restore size is %llu\n", Restore_Size); - return Restore_Size; +unsigned long long TWPartition::Get_Restore_Size(PartitionSettings *part_settings) { + if (!part_settings->adbbackup) { + InfoManager restore_info(part_settings->Restore_Name + "/" + Backup_Name + ".info"); + if (restore_info.LoadValues() == 0) { + if (restore_info.GetValue("backup_size", Restore_Size) == 0) { + LOGINFO("Read info file, restore size is %llu\n", Restore_Size); + return Restore_Size; + } } } - string Full_FileName, Restore_File_System = Get_Restore_File_System(restore_folder); - Full_FileName = restore_folder + "/" + Backup_FileName; + string Full_FileName, Restore_File_System = Get_Restore_File_System(part_settings); + Full_FileName = part_settings->Restore_Name + "/" + Backup_FileName; if (Is_Image(Restore_File_System)) { Restore_Size = TWFunc::Get_File_Size(Full_FileName); return Restore_Size; @@ -2309,7 +2354,7 @@ unsigned long long TWPartition::Get_Restore_Size(const string& restore_folder) { twrpTar tar; tar.setdir(Backup_Path); tar.setfn(Full_FileName); - tar.backup_name = Backup_Name; + tar.backup_name = Full_FileName; #ifndef TW_EXCLUDE_ENCRYPTED_BACKUPS string Password; DataManager::GetValue("tw_restore_password", Password); @@ -2317,14 +2362,16 @@ unsigned long long TWPartition::Get_Restore_Size(const string& restore_folder) { tar.setpassword(Password); #endif tar.partition_name = Backup_Name; - tar.backup_folder = restore_folder; + tar.backup_folder = part_settings->Restore_Name; + tar.part_settings = part_settings; Restore_Size = tar.get_size(); return Restore_Size; } -bool TWPartition::Restore_Tar(const string& restore_folder, const string& Restore_File_System, ProgressTracking *progress) { +bool TWPartition::Restore_Tar(PartitionSettings *part_settings) { string Full_FileName; bool ret = false; + string Restore_File_System = Get_Restore_File_System(part_settings); if (Has_Android_Secure) { if (!Wipe_AndSec()) @@ -2347,8 +2394,9 @@ bool TWPartition::Restore_Tar(const string& restore_folder, const string& Restor if (!ReMount_RW(true)) return false; - Full_FileName = restore_folder + "/" + Backup_FileName; + Full_FileName = part_settings->Restore_Name + "/" + part_settings->Backup_FileName; twrpTar tar; + tar.part_settings = part_settings; tar.setdir(Backup_Path); tar.setfn(Full_FileName); tar.backup_name = Backup_Name; @@ -2358,8 +2406,8 @@ bool TWPartition::Restore_Tar(const string& restore_folder, const string& Restor if (!Password.empty()) tar.setpassword(Password); #endif - progress->SetPartitionSize(Get_Restore_Size(restore_folder)); - if (tar.extractTarFork(progress) != 0) + part_settings->progress->SetPartitionSize(Get_Restore_Size(part_settings)); + if (tar.extractTarFork() != 0) ret = false; else ret = true; @@ -2389,19 +2437,30 @@ bool TWPartition::Restore_Tar(const string& restore_folder, const string& Restor return ret; } -bool TWPartition::Restore_Image(const string& restore_folder, const string& Restore_File_System, ProgressTracking *progress) { +bool TWPartition::Restore_Image(PartitionSettings *part_settings) { string Full_FileName; + string Restore_File_System = Get_Restore_File_System(part_settings); TWFunc::GUI_Operation_Text(TW_RESTORE_TEXT, Backup_Display_Name, gui_parse_text("{@restoring_hdr}")); gui_msg(Msg("restoring=Restoring {1}...")(Backup_Display_Name)); - Full_FileName = restore_folder + "/" + Backup_FileName; + + if (part_settings->adbbackup) + Full_FileName = TW_ADB_RESTORE; + else + Full_FileName = part_settings->Full_Backup_Path + part_settings->Backup_FileName; if (Restore_File_System == "emmc") { - unsigned long long file_size = (unsigned long long)(TWFunc::Get_File_Size(Full_FileName)); - if (!Raw_Read_Write(Full_FileName, Actual_Block_Device, file_size, progress)) + if (!part_settings->adbbackup) + part_settings->total_restore_size = (uint64_t)(TWFunc::Get_File_Size(Full_FileName)); + if (!Raw_Read_Write(part_settings)) return false; } else if (Restore_File_System == "mtd" || Restore_File_System == "bml") { - if (!Flash_Image_FI(Full_FileName, progress)) + if (!Flash_Image_FI(Full_FileName, part_settings->progress)) + return false; + } + + if (part_settings->adbbackup) { + if (!twadbbu::Write_TWEOF()) return false; } return true; @@ -2544,12 +2603,14 @@ uint64_t TWPartition::Get_Max_FileSize() { return maxFileSize - 1; } -bool TWPartition::Flash_Image(const string& Filename) { - string Restore_File_System; +bool TWPartition::Flash_Image(PartitionSettings *part_settings) { + string Restore_File_System, full_filename; + + full_filename = part_settings->Restore_Name + "/" + part_settings->Backup_FileName; - LOGINFO("Image filename is: %s\n", Filename.c_str()); + LOGINFO("Image filename is: %s\n", part_settings->Backup_FileName.c_str()); - if (Backup_Method == FILES) { + if (Backup_Method == BM_FILES) { LOGERR("Cannot flash images to file systems\n"); return false; } else if (!Can_Flash_Img) { @@ -2560,22 +2621,23 @@ bool TWPartition::Flash_Image(const string& Filename) { LOGERR("Unable to find partition size for '%s'\n", Mount_Point.c_str()); return false; } - unsigned long long image_size = TWFunc::Get_File_Size(Filename); + unsigned long long image_size = TWFunc::Get_File_Size(full_filename); if (image_size > Size) { LOGINFO("Size (%llu bytes) of image '%s' is larger than target device '%s' (%llu bytes)\n", - image_size, Filename.c_str(), Actual_Block_Device.c_str(), Size); + image_size, part_settings->Backup_FileName.c_str(), Actual_Block_Device.c_str(), Size); gui_err("img_size_err=Size of image is larger than target device"); return false; } - if (Backup_Method == DD) { - if (Is_Sparse_Image(Filename)) { - return Flash_Sparse_Image(Filename); + if (Backup_Method == BM_DD) { + if (!part_settings->adbbackup) { + if (Is_Sparse_Image(full_filename)) { + return Flash_Sparse_Image(full_filename); + } } - unsigned long long file_size = (unsigned long long)(TWFunc::Get_File_Size(Filename)); - ProgressTracking pt(file_size); - return Raw_Read_Write(Filename, Actual_Block_Device, file_size, &pt); - } else if (Backup_Method == FLASH_UTILS) { - return Flash_Image_FI(Filename, NULL); + unsigned long long file_size = (unsigned long long)(TWFunc::Get_File_Size(full_filename)); + return Raw_Read_Write(part_settings); + } else if (Backup_Method == BM_FLASH_UTILS) { + return Flash_Image_FI(full_filename, NULL); } } @@ -2590,6 +2652,7 @@ bool TWPartition::Is_Sparse_Image(const string& Filename) { gui_msg(Msg(msg::kError, "error_opening_strerr=Error opening: '{1}' ({2})")(Filename)(strerror(errno))); return false; } + if (read(fd, &magic, sizeof(magic)) != sizeof(magic)) { gui_msg(Msg(msg::kError, "error_opening_strerr=Error opening: '{1}' ({2})")(Filename)(strerror(errno))); close(fd); @@ -2637,6 +2700,10 @@ void TWPartition::Change_Mount_Read_Only(bool new_value) { Mount_Read_Only = new_value; } +bool TWPartition::Is_Read_Only() { + return Mount_Read_Only; +} + int TWPartition::Check_Lifetime_Writes() { bool original_read_only = Mount_Read_Only; int ret = 1; |