diff --git a/Android.mk b/Android.mk index bc6341e2..6ac46335 100755 --- a/Android.mk +++ b/Android.mk @@ -62,6 +62,7 @@ LOCAL_SRC_FILES := \ find_file.cpp \ infomanager.cpp \ data.cpp \ + kernel_module_loader.cpp \ partition.cpp \ partitionmanager.cpp \ progresstracking.cpp \ @@ -155,7 +156,10 @@ endif ifeq ($(PRODUCT_USE_DYNAMIC_PARTITIONS),true) LOCAL_CFLAGS += -DPRODUCT_USE_DYNAMIC_PARTITIONS=1 TWRP_REQUIRED_MODULES += android.hardware.health@2.1-service android.hardware.health@2.1-impl.recovery android.hardware.health@2.1-service.rc android.hardware.health@2.1.xml - TWRP_REQUIRED_MODULES += android.hardware.health@2.0-service android.hardware.health@2.0-impl.recovery android.hardware.health@2.0-service.rc + TWRP_REQUIRED_MODULES += android.hardware.health@2.0-service android.hardware.health@2.0-impl.recovery android.hardware.health@2.0-service.rc + TWRP_REQUIRED_MODULES += libmodprobe + LOCAL_C_INCLUDES += system/core/libmodprobe/include/ + LOCAL_STATIC_LIBRARIES += libmodprobe ifeq ($(TW_EXCLUDE_LPDUMP),) TWRP_REQUIRED_MODULES += lpdump lpdumpd.rc endif @@ -297,6 +301,9 @@ endif ifneq ($(TW_ADDITIONAL_APEX_FILES),) LOCAL_CFLAGS += -DTW_ADDITIONAL_APEX_FILES=$(TW_ADDITIONAL_APEX_FILES) endif +ifneq ($(TW_LOAD_VENDOR_MODULES),) + LOCAL_CFLAGS += -DTW_LOAD_VENDOR_MODULES=$(TW_LOAD_VENDOR_MODULES) +endif ifeq ($(TW_INCLUDE_CRYPTO), true) LOCAL_CFLAGS += -DTW_INCLUDE_CRYPTO -DUSE_FSCRYPT -Wno-macro-redefined LOCAL_SHARED_LIBRARIES += libcryptfsfde diff --git a/kernel_module_loader.cpp b/kernel_module_loader.cpp new file mode 100644 index 00000000..fd24a919 --- /dev/null +++ b/kernel_module_loader.cpp @@ -0,0 +1,121 @@ +#include "kernel_module_loader.hpp" + +bool KernelModuleLoader::Load_Vendor_Modules(BOOT_MODE mode) { + // check /lib/modules (ramdisk vendor_boot) + // check /lib/modules/N.N (ramdisk vendor_boot) + // check /lib/modules/N.N-gki (ramdisk vendor_boot) + // check /vendor/lib/modules (ramdisk) + // check /vendor/lib/modules/1.1 (ramdisk prebuilt modules) + // check /vendor/lib/modules/N.N (vendor mounted) + // check /vendor/lib/modules/N.N-gki (vendor mounted) + + LOGINFO("Attempting to load modules\n"); + std::string vendor_base_dir(VENDOR_MODULE_DIR); + std::string base_dir(VENDOR_BOOT_MODULE_DIR); + std::vector module_dirs; + std::vector vendor_module_dirs; + + TWPartition* ven = PartitionManager.Find_Partition_By_Path("/vendor"); + vendor_module_dirs.push_back(VENDOR_MODULE_DIR); + vendor_module_dirs.push_back(vendor_base_dir + "/1.1"); + + module_dirs.push_back(base_dir); + + struct utsname uts; + if (uname(&uts)) { + LOGERR("Unable to query kernel for version info\n"); + } + + std::string rls(uts.release); + std::vector release = TWFunc::split_string(rls, '.', true); + module_dirs.push_back(base_dir + "/" + release[0] + "." + release[1]); + + for (auto&& module_dir:module_dirs) { + Try_And_Load_Modules(module_dir); + } + + for (auto&& module_dir:vendor_module_dirs) { + Try_And_Load_Modules(module_dir); + } + + if (ven) { + LOGINFO("Checking mounted /vendor\n"); + ven->Mount(true); + } + + for (auto&& module_dir:vendor_module_dirs) { + Try_And_Load_Modules(module_dir); + } + + if (ven) + ven->UnMount(false); + + return true; +} + +bool KernelModuleLoader::Try_And_Load_Modules(std::string module_dir) { + LOGINFO("Checking directory: %s\n", module_dir.c_str()); + std::string dest_module_dir; + dest_module_dir = "/tmp" + module_dir; + TWFunc::Recursive_Mkdir(dest_module_dir); + Copy_Modules_To_Tmpfs(module_dir); + Write_Module_List(dest_module_dir); + Modprobe m({dest_module_dir}, "modules.load.twrp"); + m.EnableVerbose(true); + m.LoadListedModules(false); + int modules_loaded = m.GetModuleCount(); + LOGINFO("Modules Loaded: %d\n", modules_loaded); + return modules_loaded > 0 ? true : false; +} + +bool KernelModuleLoader::Write_Module_List(std::string module_dir) { + DIR* d; + struct dirent* de; + std::vector kernel_modules; + std::vector kernel_modules_requested = TWFunc::split_string(EXPAND(TW_LOAD_VENDOR_MODULES), ' ', true); + d = opendir(module_dir.c_str()); + if (d != nullptr) { + while ((de = readdir(d)) != nullptr) { + std::string kernel_module = de->d_name; + if (de->d_type == DT_REG) { + if (android::base::EndsWith(kernel_module, ".ko")) { + for (auto&& requested:kernel_modules_requested) { + if (kernel_module == requested) { + kernel_modules.push_back(kernel_module); + continue; + } + } + continue; + } + } + } + std::string module_file = module_dir + "/modules.load.twrp"; + TWFunc::write_to_file(module_file, kernel_modules); + closedir(d); + } + return true; +} + +bool KernelModuleLoader::Copy_Modules_To_Tmpfs(std::string module_dir) { + std::string ramdisk_dir = "/tmp" + module_dir; + DIR* d; + struct dirent* de; + d = opendir(module_dir.c_str()); + if (d != nullptr) { + while ((de = readdir(d)) != nullptr) { + std::string kernel_module = de->d_name; + if (de->d_type == DT_REG) { + std::string src = module_dir + "/" + de->d_name; + std::string dest = ramdisk_dir + "/" + de->d_name; + if (TWFunc::copy_file(src, dest, 0700, false) != 0) { + return false; + } + } + } + closedir(d); + } else { + LOGINFO("Unable to open module directory: %s. Skipping\n", module_dir.c_str()); + return false; + } + return true; +} \ No newline at end of file diff --git a/kernel_module_loader.hpp b/kernel_module_loader.hpp new file mode 100644 index 00000000..fe890316 --- /dev/null +++ b/kernel_module_loader.hpp @@ -0,0 +1,33 @@ +#ifndef _KERNELMODULELOADER_HPP +#define _KERNELMODULELOADER_HPP + +#include +#include +#include +#include +#include +#include + +#include "twcommon.h" +#include "twrp-functions.hpp" + +#define VENDOR_MODULE_DIR "/vendor/lib/modules" // Base path for vendor kernel modules to check by TWRP +#define VENDOR_BOOT_MODULE_DIR "/lib/modules" // vendor_boot ramdisk GKI modules to check by TWRP +typedef enum { + RECOVERY_FASTBOOT_MODE = 0, + RECOVERY_IN_BOOT_MODE, + FASTBOOTD_MODE +} BOOT_MODE; + +class KernelModuleLoader +{ +public: + static bool Load_Vendor_Modules(BOOT_MODE mode); // Load specific maintainer defined kernel modules in TWRP + +private: + static bool Try_And_Load_Modules(std::string module_dir); // Use libmodprobe to attempt loading kernel modules + static bool Write_Module_List(std::string module_dir); // Write list of modules to load from TW_LOAD_VENDOR_MODULES + static bool Copy_Modules_To_Tmpfs(std::string module_dir); // Copy modules to ramdisk for loading +}; + +#endif // _KERNELMODULELOADER_HPP \ No newline at end of file diff --git a/partitionmanager.cpp b/partitionmanager.cpp index 2b8a3fd7..481d8d80 100755 --- a/partitionmanager.cpp +++ b/partitionmanager.cpp @@ -148,12 +148,9 @@ int TWPartitionManager::Set_FDE_Encrypt_Status(void) { return 0; } -int TWPartitionManager::Process_Fstab(string Fstab_Filename, bool Display_Error) { +int TWPartitionManager::Process_Fstab(string Fstab_Filename, bool Display_Error, bool recovery_mode) { FILE *fstabFile; char fstab_line[MAX_FSTAB_LINE_LENGTH]; - TWPartition* settings_partition = NULL; - TWPartition* andsec_partition = NULL; - unsigned int storageid = 1 << 16; // upper 16 bits are for physical storage device, we pretend to have only one std::map twrp_flags; fstabFile = fopen("/etc/twrp.flags", "rt"); @@ -262,114 +259,124 @@ int TWPartitionManager::Process_Fstab(string Fstab_Filename, bool Display_Error) } LOGINFO("Done processing fstab files\n"); - std::vector::iterator iter; - for (iter = Partitions.begin(); iter != Partitions.end(); iter++) { - (*iter)->Partition_Post_Processing(Display_Error); - - if ((*iter)->Is_Storage) { - ++storageid; - (*iter)->MTP_Storage_ID = storageid; - } - - if (!settings_partition && (*iter)->Is_Settings_Storage && (*iter)->Is_Present) - settings_partition = (*iter); - else - (*iter)->Is_Settings_Storage = false; - - if (!andsec_partition && (*iter)->Has_Android_Secure && (*iter)->Is_Present) - andsec_partition = (*iter); - else - (*iter)->Has_Android_Secure = false; - - if ((*iter)->Is_Super) - Prepare_Super_Volume((*iter)); + if (recovery_mode) { + Setup_Fstab_Partitions(Display_Error); } - - //Setup Apex before decryption - TWPartition* sys = PartitionManager.Find_Partition_By_Path(PartitionManager.Get_Android_Root_Path()); - TWPartition* ven = PartitionManager.Find_Partition_By_Path("/vendor"); - if (sys) { - if (sys->Get_Super_Status()) { - sys->Mount(true); - if (ven) { - ven->Mount(true); - } -#ifdef TW_EXCLUDE_APEX - LOGINFO("Apex is disabled in this build\n"); -#else - twrpApex apex; - if (!apex.loadApexImages()) { - LOGERR("Unable to load apex images from %s\n", APEX_DIR); - property_set("twrp.apex.loaded", "false"); - } else { - property_set("twrp.apex.loaded", "true"); - } - TWFunc::check_and_run_script("/sbin/resyncapex.sh", "apex"); -#endif - } - } -#ifndef USE_VENDOR_LIBS - if (ven) - ven->UnMount(true); - if (sys) - sys->UnMount(true); -#endif - - if (!datamedia && !settings_partition && Find_Partition_By_Path("/sdcard") == NULL && Find_Partition_By_Path("/internal_sd") == NULL && Find_Partition_By_Path("/internal_sdcard") == NULL && Find_Partition_By_Path("/emmc") == NULL) { - // Attempt to automatically identify /data/media emulated storage devices - TWPartition* Dat = Find_Partition_By_Path("/data"); - if (Dat) { - LOGINFO("Using automatic handling for /data/media emulated storage device.\n"); - datamedia = true; - Dat->Setup_Data_Media(); - settings_partition = Dat; - // Since /data was not considered a storage partition earlier, we still need to assign an MTP ID - ++storageid; - Dat->MTP_Storage_ID = storageid; - } - } - if (!settings_partition) { - for (iter = Partitions.begin(); iter != Partitions.end(); iter++) { - if ((*iter)->Is_Storage) { - settings_partition = (*iter); - break; - } - } - if (!settings_partition) - LOGERR("Unable to locate storage partition for storing settings file.\n"); - } - if (!Write_Fstab()) { - if (Display_Error) - LOGERR("Error creating fstab\n"); - else - LOGINFO("Error creating fstab\n"); - } - - if (andsec_partition) { - Setup_Android_Secure_Location(andsec_partition); - } else if (settings_partition) { - Setup_Android_Secure_Location(settings_partition); - } - if (settings_partition) { - Setup_Settings_Storage_Partition(settings_partition); - } - -#ifdef TW_INCLUDE_CRYPTO - DataManager::SetValue(TW_IS_ENCRYPTED, 1); - Decrypt_Data(); -#endif - - Update_System_Details(); - if (Get_Super_Status()) - Setup_Super_Partition(); - UnMount_Main_Partitions(); -#ifdef AB_OTA_UPDATER - DataManager::SetValue("tw_active_slot", Get_Active_Slot_Display()); -#endif - setup_uevent(); return true; } +void TWPartitionManager::Setup_Fstab_Partitions(bool Display_Error) { + TWPartition* settings_partition = NULL; + TWPartition* andsec_partition = NULL; + std::vector::iterator iter; + unsigned int storageid = 1 << 16; // upper 16 bits are for physical storage device, we pretend to have only one + + for (iter = Partitions.begin(); iter != Partitions.end(); iter++) { + (*iter)->Partition_Post_Processing(Display_Error); + + if ((*iter)->Is_Storage) { + ++storageid; + (*iter)->MTP_Storage_ID = storageid; + } + + if (!settings_partition && (*iter)->Is_Settings_Storage && (*iter)->Is_Present) + settings_partition = (*iter); + else + (*iter)->Is_Settings_Storage = false; + + if (!andsec_partition && (*iter)->Has_Android_Secure && (*iter)->Is_Present) + andsec_partition = (*iter); + else + (*iter)->Has_Android_Secure = false; + + if ((*iter)->Is_Super) + Prepare_Super_Volume((*iter)); + } + + //Setup Apex before decryption + TWPartition* sys = PartitionManager.Find_Partition_By_Path(PartitionManager.Get_Android_Root_Path()); + TWPartition* ven = PartitionManager.Find_Partition_By_Path("/vendor"); + if (sys) { + if (sys->Get_Super_Status()) { + sys->Mount(true); + if (ven) { + ven->Mount(true); + } + #ifdef TW_EXCLUDE_APEX + LOGINFO("Apex is disabled in this build\n"); + #else + twrpApex apex; + if (!apex.loadApexImages()) { + LOGERR("Unable to load apex images from %s\n", APEX_DIR); + property_set("twrp.apex.loaded", "false"); + } else { + property_set("twrp.apex.loaded", "true"); + } + TWFunc::check_and_run_script("/sbin/resyncapex.sh", "apex"); + #endif + } + } + #ifndef USE_VENDOR_LIBS + if (ven) + ven->UnMount(true); + if (sys) + sys->UnMount(true); + #endif + + if (!datamedia && !settings_partition && Find_Partition_By_Path("/sdcard") == NULL && Find_Partition_By_Path("/internal_sd") == NULL && Find_Partition_By_Path("/internal_sdcard") == NULL && Find_Partition_By_Path("/emmc") == NULL) { + // Attempt to automatically identify /data/media emulated storage devices + TWPartition* Dat = Find_Partition_By_Path("/data"); + if (Dat) { + LOGINFO("Using automatic handling for /data/media emulated storage device.\n"); + datamedia = true; + Dat->Setup_Data_Media(); + settings_partition = Dat; + // Since /data was not considered a storage partition earlier, we still need to assign an MTP ID + ++storageid; + Dat->MTP_Storage_ID = storageid; + } + } + if (!settings_partition) { + for (iter = Partitions.begin(); iter != Partitions.end(); iter++) { + if ((*iter)->Is_Storage) { + settings_partition = (*iter); + break; + } + } + if (!settings_partition) + LOGERR("Unable to locate storage partition for storing settings file.\n"); + } + if (!Write_Fstab()) { + if (Display_Error) + LOGERR("Error creating fstab\n"); + else + LOGINFO("Error creating fstab\n"); + } + + if (andsec_partition) { + Setup_Android_Secure_Location(andsec_partition); + } else if (settings_partition) { + Setup_Android_Secure_Location(settings_partition); + } + if (settings_partition) { + Setup_Settings_Storage_Partition(settings_partition); + } + + #ifdef TW_INCLUDE_CRYPTO + DataManager::SetValue(TW_IS_ENCRYPTED, 1); + Decrypt_Data(); + #endif + + Update_System_Details(); + if (Get_Super_Status()) + Setup_Super_Partition(); + UnMount_Main_Partitions(); + #ifdef AB_OTA_UPDATER + DataManager::SetValue("tw_active_slot", Get_Active_Slot_Display()); + #endif + setup_uevent(); +} + int TWPartitionManager::Write_Fstab(void) { FILE *fp; std::vector::iterator iter; @@ -618,8 +625,6 @@ int TWPartitionManager::Mount_By_Path(string Path, bool Display_Error) { return ret; } else if (Display_Error) { gui_msg(Msg(msg::kError, "unable_find_part_path=Unable to find partition for path '{1}'")(Local_Path)); - } else { - LOGINFO("Mount: Unable to find partition for path '%s'\n", Local_Path.c_str()); } return false; } @@ -2085,7 +2090,7 @@ int TWPartitionManager::Open_Lun_File(string Partition_Path, string Lun_File) { if (!Part->UnMount(true) || !Part->Is_Present) return false; - if (TWFunc::write_to_file(Lun_File, Part->Actual_Block_Device)) { + if (!TWFunc::write_to_file(Lun_File, Part->Actual_Block_Device)) { LOGERR("Unable to write to ums lunfile '%s': (%s)\n", Lun_File.c_str(), strerror(errno)); return false; } @@ -2151,15 +2156,15 @@ error_handle: } int TWPartitionManager::usb_storage_disable(void) { - int index, ret; + int index, ret = 0; char lun_file[255], ch[2] = {0, 0}; string str = ch; for (index=0; index<2; index++) { sprintf(lun_file, CUSTOM_LUN_FILE, index); - ret = TWFunc::write_to_file(lun_file, str); - if (ret < 0) { + if (!TWFunc::write_to_file(lun_file, str)) { break; + ret = -1; } } Mount_All_Storage(); diff --git a/partitions.hpp b/partitions.hpp index 936d99b9..4d432c37 100755 --- a/partitions.hpp +++ b/partitions.hpp @@ -317,7 +317,8 @@ public: ~TWPartitionManager() {} public: - int Process_Fstab(string Fstab_Filename, bool Display_Error); // Parses the fstab and populates the partitions + int Process_Fstab(string Fstab_Filename, bool Display_Error, bool recovery_mode); // Parses the fstab files + void Setup_Fstab_Partitions(bool Display_Error); // Populates the partitions int Write_Fstab(); // Creates /etc/fstab file that's used by the command line for mount commands void Decrypt_Data(); // Decrypt Data if enabled void Output_Partition_Logging(); // Outputs partition information to the log diff --git a/twrp-functions.cpp b/twrp-functions.cpp index c56e194e..0f7ebb39 100755 --- a/twrp-functions.cpp +++ b/twrp-functions.cpp @@ -38,6 +38,9 @@ #include #include #include + +#include + #include "twrp-functions.hpp" #include "twcommon.h" #include "gui/gui.hpp" @@ -694,11 +697,13 @@ int TWFunc::removeDir(const string path, bool skipParent) { return r; } -int TWFunc::copy_file(string src, string dst, int mode) { - PartitionManager.Mount_By_Path(src, false); - PartitionManager.Mount_By_Path(dst, false); +int TWFunc::copy_file(string src, string dst, int mode, bool mount_paths) { + if (mount_paths) { + PartitionManager.Mount_By_Path(src, false); + PartitionManager.Mount_By_Path(dst, false); + } if (!Path_Exists(src)) { - LOGINFO("Path %s does not exist. Unable to copy %s\n", src.c_str(), dst.c_str()); + LOGINFO("Path %s does not exist. Unable to copy file to %s\n", src.c_str(), dst.c_str()); return -1; } std::ifstream srcfile(src.c_str(), ios::binary); @@ -714,8 +719,10 @@ int TWFunc::copy_file(string src, string dst, int mode) { srcfile.close(); dstfile.close(); - if (chmod(dst.c_str(), mode) != 0) + if (chmod(dst.c_str(), mode) != 0) { + LOGERR("Unable to chmod file: %s. Error: %s\n", dst.c_str(), strerror(errno)); return -1; + } return 0; } @@ -745,7 +752,10 @@ int TWFunc::read_file(string fn, string& results) { file.open(fn.c_str(), ios::in); if (file.is_open()) { - file >> results; + std::string line; + while (std::getline(file, line)) { + results += line; + } file.close(); return 0; } @@ -782,18 +792,33 @@ int TWFunc::read_file(string fn, uint64_t& results) { return -1; } -int TWFunc::write_to_file(const string& fn, const string& line) { +bool TWFunc::write_to_file(const string& fn, const string& line) { FILE *file; file = fopen(fn.c_str(), "w"); if (file != NULL) { fwrite(line.c_str(), line.size(), 1, file); fclose(file); - return 0; + return true; } LOGINFO("Cannot find file %s\n", fn.c_str()); - return -1; + return false; } +bool TWFunc::write_to_file(const string& fn, const std::vector lines) { + FILE *file; + file = fopen(fn.c_str(), "a+"); + if (file != NULL) { + for (auto&& line: lines) { + fwrite(line.c_str(), line.size(), 1, file); + fwrite("\n", sizeof(char), 1, file); + } + fclose(file); + return true; + } + return false; +} + + bool TWFunc::Try_Decrypting_Backup(string Restore_Path, string Password) { DIR* d; @@ -1086,7 +1111,7 @@ int TWFunc::Set_Brightness(std::string brightness_value) TWFunc::write_to_file(secondary_brightness_file, brightness_value); } } - return result; + return result ? 0 : -1; } bool TWFunc::Toggle_MTP(bool enable) { diff --git a/twrp-functions.hpp b/twrp-functions.hpp index dc51454d..77ca1a23 100755 --- a/twrp-functions.hpp +++ b/twrp-functions.hpp @@ -30,8 +30,8 @@ using namespace std; -#define CACHE_LOGS_DIR "/cache/" // For devices with a dedicated cache partition -#define DATA_LOGS_DIR "/data/" // For devices that do not have a dedicated cache partition +#define CACHE_LOGS_DIR "/cache/" // For devices with a dedicated cache partition +#define DATA_LOGS_DIR "/data/" // For devices that do not have a dedicated cache partition typedef enum { @@ -87,12 +87,13 @@ public: static int tw_reboot(RebootCommand command); // Prepares the device for rebooting static void check_and_run_script(const char* script_file, const char* display_name); // checks for the existence of a script, chmods it to 755, then runs it static int removeDir(const string path, bool removeParent); //recursively remove a directory - static int copy_file(string src, string dst, int mode); //copy file from src to dst with mode permissions + static int copy_file(string src, string dst, int mode, bool mount_paths=true); //copy file from src to dst with mode permissions static unsigned int Get_D_Type_From_Stat(string Path); // Returns a dirent dt_type value using stat instead of dirent static int read_file(string fn, vector& results); //read from file static int read_file(string fn, string& results); //read from file static int read_file(string fn, uint64_t& results); //read from file - static int write_to_file(const string& fn, const string& line); //write to file + static bool write_to_file(const string& fn, const string& line); //write single line to file with no newline + static bool write_to_file(const string& fn, const std::vector lines); // write vector of strings line by line with newlines static bool Try_Decrypting_Backup(string Restore_Path, string Password); // true for success, false for failed to decrypt static string System_Property_Get(string Prop_Name); // Returns value of Prop_Name from reading /system/build.prop static string System_Property_Get(string Prop_Name, TWPartitionManager &PartitionManager, string Mount_Point); // Returns value of Prop_Name from reading /system/build.prop @@ -125,9 +126,9 @@ public: static bool Set_Encryption_Policy(std::string path, struct fscrypt_policy_v2 &policy); // set encryption policy for path #endif #endif - static void List_Mounts(); - static void Clear_Bootloader_Message(); - static string Check_For_TwrpFolder(); + static void List_Mounts(); // List current mounts by the kernel + static void Clear_Bootloader_Message(); // Removes the bootloader message from misc for next boot + static string Check_For_TwrpFolder(); // Gets user defined path on storage where backups should be stored private: static void Copy_Log(string Source, string Destination); diff --git a/twrp.cpp b/twrp.cpp index 6de0e627..1b0e337b 100644 --- a/twrp.cpp +++ b/twrp.cpp @@ -44,6 +44,7 @@ extern "C" { #include "twcommon.h" #include "twrp-functions.hpp" #include "data.hpp" +#include "kernel_module_loader.hpp" #include "partitions.hpp" #ifdef __ANDROID_API_N__ #include @@ -101,9 +102,39 @@ static void Decrypt_Page(bool SkipDecryption, bool datamedia) { } } +static void process_fastbootd_mode() { + LOGINFO("starting fastboot\n"); + printf("=> Linking mtab\n"); + symlink("/proc/mounts", "/etc/mtab"); + std::string fstab_filename = "/etc/twrp.fstab"; + if (!TWFunc::Path_Exists(fstab_filename)) { + fstab_filename = "/etc/recovery.fstab"; + } + printf("=> Processing %s\n", fstab_filename.c_str()); + if (!PartitionManager.Process_Fstab(fstab_filename, 1, false)) { + LOGERR("Failing out of recovery due to problem with fstab.\n"); + return; + } + TWPartition* ven = PartitionManager.Find_Partition_By_Path("/vendor"); + PartitionManager.Setup_Super_Devices(); + PartitionManager.Prepare_Super_Volume(ven); +#ifdef TW_LOAD_VENDOR_MODULES + KernelModuleLoader::Load_Vendor_Modules(FASTBOOTD_MODE); +#endif + gui_msg(Msg("fastboot_console_msg=Entered Fastboot mode...")); + if (gui_startPage("fastboot", 1, 1) != 0) { + LOGERR("Failed to start fastbootd page.\n"); + } +} + static void process_recovery_mode(twrpAdbBuFifo* adb_bu_fifo, bool skip_decryption) { char crash_prop_val[PROPERTY_VALUE_MAX]; int crash_counter; + std::string cmdline; + if (TWFunc::read_file("/proc/cmdline", cmdline) != 0) { + LOGINFO("Unable to read cmdline for fastboot mode\n"); + } + property_get("twrp.crash_counter", crash_prop_val, "-1"); crash_counter = atoi(crash_prop_val) + 1; snprintf(crash_prop_val, sizeof(crash_prop_val), "%d", crash_counter); @@ -123,11 +154,19 @@ static void process_recovery_mode(twrpAdbBuFifo* adb_bu_fifo, bool skip_decrypti fstab_filename = "/etc/recovery.fstab"; } printf("=> Processing %s\n", fstab_filename.c_str()); - if (!PartitionManager.Process_Fstab(fstab_filename, 1)) { + if (!PartitionManager.Process_Fstab(fstab_filename, 1, true)) { LOGERR("Failing out of recovery due to problem with fstab.\n"); return; } +#ifdef TW_LOAD_VENDOR_MODULES + bool fastboot_mode = cmdline.find("twrpfastboot=1") != std::string::npos; + if (fastboot_mode) + KernelModuleLoader::Load_Vendor_Modules(RECOVERY_FASTBOOT_MODE); + else + KernelModuleLoader::Load_Vendor_Modules(RECOVERY_IN_BOOT_MODE); +#endif + // We are doing this here to allow super partition to be set up prior to overriding properties #if defined(TW_INCLUDE_LIBRESETPROP) && defined(TW_OVERRIDE_SYSTEM_PROPS) if (!PartitionManager.Mount_By_Path(PartitionManager.Get_Android_Root_Path(), true)) { @@ -340,14 +379,9 @@ int main(int argc, char **argv) { TWFunc::Clear_Bootloader_Message(); if (startup.Get_Fastboot_Mode()) { - LOGINFO("starting fastboot\n"); - gui_msg(Msg("fastboot_console_msg=Entered Fastboot mode...")); - if (gui_startPage("fastboot", 1, 1) != 0) { - LOGERR("Failed to start fastbootd page.\n"); - } + process_fastbootd_mode(); delete adb_bu_fifo; TWFunc::Update_Intent_File(startup.Get_Intent()); - reboot(); return 0; } else { @@ -363,7 +397,6 @@ int main(int argc, char **argv) { gui_start(); delete adb_bu_fifo; TWFunc::Update_Intent_File(startup.Get_Intent()); - reboot(); return 0; diff --git a/twrpDigestDriver.cpp b/twrpDigestDriver.cpp index af314179..3e21d06d 100755 --- a/twrpDigestDriver.cpp +++ b/twrpDigestDriver.cpp @@ -168,7 +168,7 @@ bool twrpDigestDriver::Write_Digest(string Full_Filename) { digest_str = digest_str + " " + TWFunc::Get_Filename(Full_Filename) + "\n"; LOGINFO("digest_filename: %s\n", digest_filename.c_str()); - if (TWFunc::write_to_file(digest_filename, digest_str) == 0) { + if (TWFunc::write_to_file(digest_filename, digest_str)) { tw_set_default_metadata(digest_filename.c_str()); gui_msg("digest_created= * Digest Created."); }