bigbiff | ad58e1b | 2020-07-06 20:24:34 -0400 | [diff] [blame] | 1 | /* |
| 2 | Copyright 2013 to 2020 TeamWin |
| 3 | This file is part of TWRP/TeamWin Recovery Project. |
| 4 | |
| 5 | TWRP is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU General Public License as published by |
| 7 | the Free Software Foundation, either version 3 of the License, or |
| 8 | (at your option) any later version. |
| 9 | |
| 10 | TWRP is distributed in the hope that it will be useful, |
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 13 | GNU General Public License for more details. |
| 14 | |
| 15 | You should have received a copy of the GNU General Public License |
| 16 | along with TWRP. If not, see <http://www.gnu.org/licenses/>. |
| 17 | */ |
| 18 | |
| 19 | #include <string> |
| 20 | |
| 21 | #include "data.hpp" |
| 22 | #include "partitions.hpp" |
| 23 | #include "twrp-functions.hpp" |
| 24 | #include "twrpRepacker.hpp" |
| 25 | #include "twcommon.h" |
| 26 | #include "variables.h" |
| 27 | #include "gui/gui.hpp" |
| 28 | |
| 29 | bool twrpRepacker::Prepare_Empty_Folder(const std::string& Folder) { |
| 30 | if (TWFunc::Path_Exists(Folder)) |
| 31 | TWFunc::removeDir(Folder, false); |
| 32 | return TWFunc::Recursive_Mkdir(Folder); |
| 33 | } |
| 34 | |
| 35 | bool twrpRepacker::Backup_Image_For_Repack(TWPartition* Part, const std::string& Temp_Folder_Destination, |
| 36 | const bool Create_Backup, const std::string& Backup_Name) { |
| 37 | if (!Part) { |
| 38 | LOGERR("Partition was null!\n"); |
| 39 | return false; |
| 40 | } |
| 41 | if (!Prepare_Empty_Folder(Temp_Folder_Destination)) |
| 42 | return false; |
| 43 | std::string target_image = Temp_Folder_Destination + "boot.img"; |
| 44 | PartitionSettings part_settings; |
| 45 | part_settings.Part = Part; |
| 46 | if (Create_Backup) { |
| 47 | if (PartitionManager.Check_Backup_Name(Backup_Name, true, false) != 0) |
| 48 | return false; |
| 49 | DataManager::GetValue(TW_BACKUPS_FOLDER_VAR, part_settings.Backup_Folder); |
| 50 | part_settings.Backup_Folder = part_settings.Backup_Folder + "/" + TWFunc::Get_Current_Date() + " " + Backup_Name + "/"; |
| 51 | if (!TWFunc::Recursive_Mkdir(part_settings.Backup_Folder)) |
| 52 | return false; |
| 53 | } else |
| 54 | part_settings.Backup_Folder = Temp_Folder_Destination; |
| 55 | part_settings.adbbackup = false; |
| 56 | part_settings.generate_digest = false; |
| 57 | part_settings.generate_md5 = false; |
| 58 | part_settings.PM_Method = PM_BACKUP; |
| 59 | part_settings.progress = NULL; |
| 60 | pid_t not_a_pid = 0; |
| 61 | if (!Part->Backup(&part_settings, ¬_a_pid)) |
| 62 | return false; |
| 63 | std::string backed_up_image = part_settings.Backup_Folder; |
| 64 | backed_up_image += Part->Get_Backup_FileName(); |
| 65 | target_image = Temp_Folder_Destination + "boot.img"; |
| 66 | if (Create_Backup) { |
| 67 | std::string source = part_settings.Backup_Folder + Part->Get_Backup_FileName(); |
| 68 | if (TWFunc::copy_file(source, target_image, 0644) != 0) { |
| 69 | LOGERR("Failed to copy backup file '%s' to temp folder target '%s'\n", source.c_str(), target_image.c_str()); |
| 70 | return false; |
| 71 | } |
| 72 | } else { |
| 73 | if (rename(backed_up_image.c_str(), target_image.c_str()) != 0) { |
| 74 | LOGERR("Failed to rename '%s' to '%s'\n", backed_up_image.c_str(), target_image.c_str()); |
| 75 | return false; |
| 76 | } |
| 77 | } |
| 78 | original_ramdisk_format = Unpack_Image(target_image, Temp_Folder_Destination, false, false); |
| 79 | return !original_ramdisk_format.empty(); |
| 80 | } |
| 81 | |
| 82 | std::string twrpRepacker::Unpack_Image(const std::string& Source_Path, const std::string& Temp_Folder_Destination, |
| 83 | const bool Copy_Source, const bool Create_Destination) { |
| 84 | std::string txt_to_find = "RAMDISK_FMT"; |
| 85 | if (Create_Destination) { |
| 86 | if (!Prepare_Empty_Folder(Temp_Folder_Destination)) |
| 87 | return std::string(); |
| 88 | } |
| 89 | if (Copy_Source) { |
| 90 | std::string destination = Temp_Folder_Destination + "/boot.img"; |
| 91 | if (TWFunc::copy_file(Source_Path, destination, 0644)) |
| 92 | return std::string(); |
| 93 | } |
nebrassy | afb12ee | 2021-09-02 09:27:54 -0400 | [diff] [blame] | 94 | std::string command = "cd " + Temp_Folder_Destination + " && /system/bin/magiskboot unpack -h -n "; |
bigbiff | ad58e1b | 2020-07-06 20:24:34 -0400 | [diff] [blame] | 95 | command = command + "'" + Source_Path +"'"; |
| 96 | |
| 97 | std::string magisk_unpack_output; |
| 98 | int ret; |
| 99 | if ((ret = TWFunc::Exec_Cmd(command, magisk_unpack_output, true)) != 0) { |
| 100 | LOGINFO("Error unpacking %s, ret: %d!\n", Source_Path.c_str(), ret); |
| 101 | gui_msg(Msg(msg::kError, "unpack_error=Error unpacking image.")); |
| 102 | return std::string(); |
| 103 | } |
sekaiacg | a28a9f3 | 2024-02-08 16:17:31 +0800 | [diff] [blame] | 104 | std::string ramdisk_format; |
| 105 | auto pos = magisk_unpack_output.find(txt_to_find); |
| 106 | if (pos != std::string::npos) { |
| 107 | auto start = magisk_unpack_output.find('[', pos + txt_to_find.size()); |
| 108 | if (start != std::string::npos) { |
| 109 | auto end = magisk_unpack_output.find(']', start); |
| 110 | if (end != std::string::npos) { |
| 111 | ramdisk_format = std::move(magisk_unpack_output.substr(start + 1, end - start - 1)); |
| 112 | } |
| 113 | } |
| 114 | } |
bigbiff | ad58e1b | 2020-07-06 20:24:34 -0400 | [diff] [blame] | 115 | return ramdisk_format; |
| 116 | } |
| 117 | |
Darth9 | 8af7fe2 | 2024-01-18 20:00:44 +0000 | [diff] [blame] | 118 | static bool is_AB_for_repacker() { |
| 119 | std::string slot = android::base::GetProperty("ro.boot.slot_suffix", ""); |
| 120 | if (slot.empty()) |
| 121 | slot = android::base::GetProperty("ro.boot.slot", ""); |
| 122 | return !slot.empty(); |
| 123 | } |
bigbiff | ad58e1b | 2020-07-06 20:24:34 -0400 | [diff] [blame] | 124 | |
Darth9 | 8af7fe2 | 2024-01-18 20:00:44 +0000 | [diff] [blame] | 125 | bool twrpRepacker::Repack_Image_And_Flash(const std::string& Target_Image, const struct Repack_Options_struct& Repack_Options) { |
bigbiff | ad58e1b | 2020-07-06 20:24:34 -0400 | [diff] [blame] | 126 | if (!TWFunc::Path_Exists("/system/bin/magiskboot")) { |
| 127 | LOGERR("Image repacking tool not present in this TWRP build!"); |
| 128 | return false; |
| 129 | } |
Darth9 | 8af7fe2 | 2024-01-18 20:00:44 +0000 | [diff] [blame] | 130 | |
| 131 | bool recompress = false; |
| 132 | bool is_vendor_boot = false; |
| 133 | bool is_vendor_boot_v4 = false; |
| 134 | std::string dest_partition = "/boot"; |
| 135 | std::string ramdisk_cpio = "ramdisk.cpio"; |
| 136 | |
| 137 | #ifdef BOARD_MOVE_RECOVERY_RESOURCES_TO_VENDOR_BOOT |
| 138 | dest_partition = "/vendor_boot"; |
| 139 | is_vendor_boot = true; |
| 140 | if (DataManager::GetIntValue("tw_boot_header_version") == 4) { |
| 141 | is_vendor_boot_v4 = true; |
| 142 | ramdisk_cpio = "vendor_ramdisk_recovery.cpio"; |
| 143 | LOGINFO("Vendor_boot with v4 header\n"); |
| 144 | } else { |
| 145 | LOGINFO("Vendor_boot with v3 header\n"); |
| 146 | } |
| 147 | #else |
| 148 | // we shouldn't reach here, because of the code in twrpRepacker::Flash_Current_Twrp(); but if we do, then handle it |
| 149 | if (PartitionManager.Find_Partition_By_Path("/recovery") && is_AB_for_repacker()) { |
| 150 | dest_partition = "/recovery"; |
| 151 | } |
| 152 | #endif |
| 153 | |
| 154 | if (is_vendor_boot || is_vendor_boot_v4) { |
| 155 | // placeholder for any specific vendor_boot stuff; |
| 156 | // in the meantime, stop the compiler's complaints about unused variables |
| 157 | } |
| 158 | |
bigbiff | ad58e1b | 2020-07-06 20:24:34 -0400 | [diff] [blame] | 159 | DataManager::SetProgress(0); |
nebrassy | 45f66b2 | 2021-07-26 22:34:24 +0200 | [diff] [blame] | 160 | PartitionManager.Update_System_Details(); |
Darth9 | 8af7fe2 | 2024-01-18 20:00:44 +0000 | [diff] [blame] | 161 | TWPartition* part = PartitionManager.Find_Partition_By_Path(dest_partition); |
bigbiff | ad58e1b | 2020-07-06 20:24:34 -0400 | [diff] [blame] | 162 | if (part) |
| 163 | gui_msg(Msg("unpacking_image=Unpacking {1}...")(part->Get_Display_Name())); |
| 164 | else { |
Darth9 | 8af7fe2 | 2024-01-18 20:00:44 +0000 | [diff] [blame] | 165 | gui_msg(Msg(msg::kError, "unable_to_locate=Unable to locate {1}.")(dest_partition.c_str())); |
bigbiff | ad58e1b | 2020-07-06 20:24:34 -0400 | [diff] [blame] | 166 | return false; |
| 167 | } |
| 168 | if (!Backup_Image_For_Repack(part, REPACK_ORIG_DIR, Repack_Options.Backup_First, gui_lookup("repack", "Repack"))) |
| 169 | return false; |
| 170 | DataManager::SetProgress(.25); |
nebrassy | ac29e69 | 2021-05-20 13:03:30 +0200 | [diff] [blame] | 171 | if (Repack_Options.Type == REPLACE_RAMDISK_UNPACKED) { |
| 172 | if (!Prepare_Empty_Folder(REPACK_NEW_DIR)) |
| 173 | return false; |
| 174 | image_ramdisk_format = "gzip"; |
| 175 | } else { |
| 176 | gui_msg(Msg("unpacking_image=Unpacking {1}...")(Target_Image)); |
| 177 | image_ramdisk_format = Unpack_Image(Target_Image, REPACK_NEW_DIR, true); |
| 178 | } |
bigbiff | ad58e1b | 2020-07-06 20:24:34 -0400 | [diff] [blame] | 179 | if (image_ramdisk_format.empty()) |
| 180 | return false; |
| 181 | DataManager::SetProgress(.5); |
| 182 | gui_msg(Msg("repacking_image=Repacking {1}...")(part->Get_Display_Name())); |
| 183 | std::string path = REPACK_NEW_DIR; |
| 184 | if (Repack_Options.Type == REPLACE_KERNEL) { |
| 185 | // When we replace the kernel, what we really do is copy the boot partition ramdisk into the new image's folder |
Darth9 | 8af7fe2 | 2024-01-18 20:00:44 +0000 | [diff] [blame] | 186 | if (TWFunc::copy_file(REPACK_ORIG_DIR + ramdisk_cpio, REPACK_NEW_DIR + ramdisk_cpio, 0644)) { |
bigbiff | ad58e1b | 2020-07-06 20:24:34 -0400 | [diff] [blame] | 187 | LOGERR("Failed to copy ramdisk\n"); |
| 188 | return false; |
| 189 | } |
nebrassy | ac29e69 | 2021-05-20 13:03:30 +0200 | [diff] [blame] | 190 | } else if (Repack_Options.Type == REPLACE_RAMDISK_UNPACKED) { |
Darth9 | 8af7fe2 | 2024-01-18 20:00:44 +0000 | [diff] [blame] | 191 | if (TWFunc::copy_file(Target_Image, REPACK_ORIG_DIR + ramdisk_cpio, 0644)) { |
nebrassy | ac29e69 | 2021-05-20 13:03:30 +0200 | [diff] [blame] | 192 | LOGERR("Failed to copy ramdisk\n"); |
| 193 | return false; |
| 194 | } |
Darth9 | 8af7fe2 | 2024-01-18 20:00:44 +0000 | [diff] [blame] | 195 | if (TWFunc::copy_file(Target_Image, REPACK_NEW_DIR + ramdisk_cpio, 0644)) { |
nebrassy | ac29e69 | 2021-05-20 13:03:30 +0200 | [diff] [blame] | 196 | LOGERR("Failed to copy ramdisk\n"); |
| 197 | return false; |
| 198 | } |
| 199 | path = REPACK_ORIG_DIR; |
bigbiff | ad58e1b | 2020-07-06 20:24:34 -0400 | [diff] [blame] | 200 | } else if (Repack_Options.Type == REPLACE_RAMDISK) { |
| 201 | // Repack the ramdisk |
Darth9 | 8af7fe2 | 2024-01-18 20:00:44 +0000 | [diff] [blame] | 202 | if (TWFunc::copy_file(REPACK_NEW_DIR + ramdisk_cpio, REPACK_ORIG_DIR + ramdisk_cpio, 0644)) { |
bigbiff | ad58e1b | 2020-07-06 20:24:34 -0400 | [diff] [blame] | 203 | LOGERR("Failed to copy ramdisk\n"); |
| 204 | return false; |
| 205 | } |
| 206 | path = REPACK_ORIG_DIR; |
| 207 | } else { |
| 208 | LOGERR("Invalid repacking options specified\n"); |
| 209 | return false; |
| 210 | } |
| 211 | if (Repack_Options.Disable_Verity) |
| 212 | LOGERR("Disabling verity is not implemented yet\n"); |
| 213 | if (Repack_Options.Disable_Force_Encrypt) |
| 214 | LOGERR("Disabling force encrypt is not implemented yet\n"); |
| 215 | std::string command = "cd " + path + " && /system/bin/magiskboot repack "; |
| 216 | if (original_ramdisk_format != image_ramdisk_format) { |
bigbiff | ad58e1b | 2020-07-06 20:24:34 -0400 | [diff] [blame] | 217 | recompress = true; |
| 218 | } |
| 219 | |
| 220 | command += path + "boot.img"; |
| 221 | |
| 222 | std::string orig_compressed_image(REPACK_ORIG_DIR); |
Darth9 | 8af7fe2 | 2024-01-18 20:00:44 +0000 | [diff] [blame] | 223 | orig_compressed_image += ramdisk_cpio; |
bigbiff | ad58e1b | 2020-07-06 20:24:34 -0400 | [diff] [blame] | 224 | std::string copy_compressed_image(REPACK_ORIG_DIR); |
| 225 | copy_compressed_image += "ramdisk-1.cpio"; |
| 226 | |
| 227 | if (recompress) { |
nebrassy | 7378254 | 2021-08-07 00:37:30 +0200 | [diff] [blame] | 228 | std::string decompress_cmd = "/system/bin/magiskboot decompress " + orig_compressed_image + " " + copy_compressed_image; |
| 229 | if (TWFunc::Exec_Cmd(decompress_cmd) != 0) { |
bigbiff | ad58e1b | 2020-07-06 20:24:34 -0400 | [diff] [blame] | 230 | gui_msg(Msg(msg::kError, "repack_error=Error repacking image.")); |
| 231 | return false; |
| 232 | } |
| 233 | std::rename(copy_compressed_image.c_str(), orig_compressed_image.c_str()); |
| 234 | } |
| 235 | |
| 236 | if (TWFunc::Exec_Cmd(command) != 0) { |
| 237 | gui_msg(Msg(msg::kError, "repack_error=Error repacking image.")); |
| 238 | return false; |
| 239 | } |
| 240 | |
| 241 | DataManager::SetProgress(.75); |
| 242 | std::string file = "new-boot.img"; |
Darth9 | 8af7fe2 | 2024-01-18 20:00:44 +0000 | [diff] [blame] | 243 | DataManager::SetValue("tw_flash_partition", dest_partition + ";"); |
bigbiff | ad58e1b | 2020-07-06 20:24:34 -0400 | [diff] [blame] | 244 | if (!PartitionManager.Flash_Image(path, file)) { |
| 245 | LOGINFO("Error flashing new image\n"); |
| 246 | return false; |
| 247 | } |
| 248 | DataManager::SetProgress(1); |
| 249 | TWFunc::removeDir(REPACK_ORIG_DIR, false); |
Darth9 | c9cc4ac | 2022-02-03 22:17:49 +0000 | [diff] [blame] | 250 | if (part->Is_SlotSelect()) { |
| 251 | if (Repack_Options.Type == REPLACE_RAMDISK || Repack_Options.Type == REPLACE_RAMDISK_UNPACKED) { |
| 252 | LOGINFO("Switching slots to flash ramdisk to both partitions\n"); |
| 253 | string Current_Slot = PartitionManager.Get_Active_Slot_Display(); |
| 254 | if (Current_Slot == "A") |
| 255 | PartitionManager.Override_Active_Slot("B"); |
| 256 | else |
| 257 | PartitionManager.Override_Active_Slot("A"); |
| 258 | DataManager::SetProgress(.25); |
| 259 | if (!Backup_Image_For_Repack(part, REPACK_ORIG_DIR, Repack_Options.Backup_First, gui_lookup("repack", "Repack"))) |
| 260 | return false; |
Darth9 | 8af7fe2 | 2024-01-18 20:00:44 +0000 | [diff] [blame] | 261 | if (TWFunc::copy_file(REPACK_NEW_DIR + ramdisk_cpio, REPACK_ORIG_DIR + ramdisk_cpio, 0644)) { |
Darth9 | c9cc4ac | 2022-02-03 22:17:49 +0000 | [diff] [blame] | 262 | LOGERR("Failed to copy ramdisk\n"); |
| 263 | return false; |
| 264 | } |
| 265 | path = REPACK_ORIG_DIR; |
| 266 | std::string command = "cd " + path + " && /system/bin/magiskboot repack "; |
bigbiff | ad58e1b | 2020-07-06 20:24:34 -0400 | [diff] [blame] | 267 | |
Darth9 | c9cc4ac | 2022-02-03 22:17:49 +0000 | [diff] [blame] | 268 | if (original_ramdisk_format != image_ramdisk_format) { |
| 269 | recompress = true; |
| 270 | } |
| 271 | command += path + "boot.img"; |
bigbiff | ad58e1b | 2020-07-06 20:24:34 -0400 | [diff] [blame] | 272 | |
Darth9 | c9cc4ac | 2022-02-03 22:17:49 +0000 | [diff] [blame] | 273 | if (recompress) { |
| 274 | std::string decompress_cmd = "/system/bin/magiskboot decompress " + orig_compressed_image + " " + copy_compressed_image; |
| 275 | if (TWFunc::Exec_Cmd(decompress_cmd) != 0) { |
| 276 | gui_msg(Msg(msg::kError, "repack_error=Error repacking image.")); |
| 277 | return false; |
| 278 | } |
| 279 | std::rename(copy_compressed_image.c_str(), orig_compressed_image.c_str()); |
| 280 | } |
| 281 | |
| 282 | if (TWFunc::Exec_Cmd(command) != 0) { |
bigbiff | ad58e1b | 2020-07-06 20:24:34 -0400 | [diff] [blame] | 283 | gui_msg(Msg(msg::kError, "repack_error=Error repacking image.")); |
| 284 | return false; |
| 285 | } |
Darth9 | c9cc4ac | 2022-02-03 22:17:49 +0000 | [diff] [blame] | 286 | DataManager::SetProgress(.75); |
| 287 | std::string file = "new-boot.img"; |
Darth9 | 8af7fe2 | 2024-01-18 20:00:44 +0000 | [diff] [blame] | 288 | DataManager::SetValue("tw_flash_partition", dest_partition + ";"); |
Darth9 | c9cc4ac | 2022-02-03 22:17:49 +0000 | [diff] [blame] | 289 | if (!PartitionManager.Flash_Image(path, file)) { |
| 290 | LOGINFO("Error flashing new image\n"); |
| 291 | return false; |
| 292 | } |
| 293 | DataManager::SetProgress(1); |
| 294 | TWFunc::removeDir(REPACK_ORIG_DIR, false); |
bigbiff | ad58e1b | 2020-07-06 20:24:34 -0400 | [diff] [blame] | 295 | } |
Darth9 | c9cc4ac | 2022-02-03 22:17:49 +0000 | [diff] [blame] | 296 | } |
bigbiff | d1e556a | 2021-08-07 14:34:06 -0400 | [diff] [blame] | 297 | TWFunc::removeDir(REPACK_NEW_DIR, false); |
Darth9 | 8af7fe2 | 2024-01-18 20:00:44 +0000 | [diff] [blame] | 298 | if (dest_partition == "/boot") |
| 299 | gui_msg(Msg(msg::kWarning, "repack_overwrite_warning=If device was previously rooted, then root has been overwritten and will need to be reinstalled.")); |
nebrassy | 07c4b90 | 2021-11-21 03:32:47 +0100 | [diff] [blame] | 300 | string Current_Slot = PartitionManager.Get_Active_Slot_Display(); |
Darth9 | 8af7fe2 | 2024-01-18 20:00:44 +0000 | [diff] [blame] | 301 | if (Current_Slot == "A") |
| 302 | PartitionManager.Override_Active_Slot("B"); |
| 303 | else |
| 304 | PartitionManager.Override_Active_Slot("A"); |
bigbiff | d1e556a | 2021-08-07 14:34:06 -0400 | [diff] [blame] | 305 | return true; |
bigbiff | ad58e1b | 2020-07-06 20:24:34 -0400 | [diff] [blame] | 306 | } |
nebrassy | ac29e69 | 2021-05-20 13:03:30 +0200 | [diff] [blame] | 307 | |
| 308 | bool twrpRepacker::Flash_Current_Twrp() { |
Darth9 | 8af7fe2 | 2024-01-18 20:00:44 +0000 | [diff] [blame] | 309 | // A/B with dedicated recovery partition |
| 310 | std::string slot = android::base::GetProperty("ro.boot.slot_suffix", ""); |
| 311 | if (slot.empty()) |
| 312 | slot = android::base::GetProperty("ro.boot.slot", ""); |
| 313 | if (!slot.empty() && PartitionManager.Find_Partition_By_Path("/recovery")) { |
| 314 | std::string root,src, dest; |
| 315 | std::string dest_partition = "/recovery"; |
| 316 | root = "/dev/block/bootdevice/by-name" + dest_partition; |
| 317 | if (slot == "_a" || slot == "a") { |
| 318 | src = root + "_a"; |
| 319 | dest= root + "_b"; |
| 320 | } |
| 321 | else { |
| 322 | src = root + "_b"; |
| 323 | dest= root + "_a"; |
| 324 | } |
| 325 | PartitionManager.Unlock_Block_Partitions(); |
| 326 | |
| 327 | // only copy the relevant active slot to the inactive slot, on the basis that the recovery currently running |
| 328 | // in the active slot can simply be copied over to the inactive slot, so that both have the same recovery image |
| 329 | std::string command = "dd bs=1048576 if=" + src + " of=" + dest; |
| 330 | LOGINFO("Command=%s\n", command.c_str()); |
| 331 | |
| 332 | if (TWFunc::Exec_Cmd(command) != 0) { |
| 333 | LOGERR("Failed to flash the %s image\n", dest_partition.c_str()); |
| 334 | return false; |
| 335 | } |
| 336 | else { |
| 337 | gui_print("Finished flashing the %s image\n", dest_partition.c_str()); |
| 338 | return true; |
| 339 | } |
| 340 | // if we reach here, something is awry - bale out |
| 341 | return false; |
| 342 | } |
| 343 | |
| 344 | if (!TWFunc::Path_Exists("/ramdisk-files.txt")) { |
nebrassy | ac29e69 | 2021-05-20 13:03:30 +0200 | [diff] [blame] | 345 | LOGERR("can not find ramdisk-files.txt"); |
| 346 | return false; |
sekaiacg | 067c00c | 2022-06-23 19:23:11 +0800 | [diff] [blame] | 347 | } |
| 348 | if (PartitionManager.Is_Mounted_By_Path("/vendor") && !PartitionManager.UnMount_By_Path("/vendor", false)) { |
| 349 | // Try to force umount /vendor |
| 350 | PartitionManager.UnMount_By_Path("/vendor", false, MNT_FORCE|MNT_DETACH); |
| 351 | } |
| 352 | Repack_Options_struct Repack_Options; |
| 353 | Repack_Options.Disable_Verity = false; |
| 354 | Repack_Options.Disable_Force_Encrypt = false; |
| 355 | Repack_Options.Type = REPLACE_RAMDISK_UNPACKED; |
| 356 | Repack_Options.Backup_First = DataManager::GetIntValue("tw_repack_backup_first") != 0; |
| 357 | std::string verifyfiles = "cd / && sha256sum --status -c ramdisk-files.sha256sum"; |
| 358 | if (TWFunc::Exec_Cmd(verifyfiles) != 0) { |
nebrassy | ac29e69 | 2021-05-20 13:03:30 +0200 | [diff] [blame] | 359 | gui_msg(Msg(msg::kError, "modified_ramdisk_error=ramdisk files have been modified, unable to create ramdisk to flash, fastboot boot twrp and try this option again or use the Install Recovery Ramdisk option.")); |
sekaiacg | 067c00c | 2022-06-23 19:23:11 +0800 | [diff] [blame] | 360 | return false; |
| 361 | } |
| 362 | std::string command = "cd / && /system/bin/cpio -H newc -o < ramdisk-files.txt > /tmp/currentramdisk.cpio && /system/bin/gzip -f /tmp/currentramdisk.cpio"; |
| 363 | if (TWFunc::Exec_Cmd(command) != 0) { |
| 364 | gui_msg(Msg(msg::kError, "create_ramdisk_error=failed to create ramdisk to flash.")); |
| 365 | return false; |
| 366 | } |
| 367 | if (!Repack_Image_And_Flash("/tmp/currentramdisk.cpio.gz", Repack_Options)) |
| 368 | return false; |
| 369 | else |
| 370 | return true; |
nebrassy | ac29e69 | 2021-05-20 13:03:30 +0200 | [diff] [blame] | 371 | } |