/*
	Copyright 2013 to 2020 TeamWin
	This file is part of TWRP/TeamWin Recovery Project.

	TWRP is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	TWRP is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with TWRP.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <sys/mount.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/vfs.h>
#include <unistd.h>
#include <dirent.h>
#include <fcntl.h>
#include <iostream>
#include <libgen.h>
#include <zlib.h>
#include <sstream>
#include <android-base/properties.h>
#include <libsnapshot/snapshot.h>

#include "cutils/properties.h"
#include "libblkid/include/blkid.h"
#include "variables.h"
#include "twcommon.h"
#include "partitions.hpp"
#include "data.hpp"
#include "twrp-functions.hpp"
#include "twrpTar.hpp"
#include "exclude.hpp"
#include "infomanager.hpp"
#include "set_metadata.h"
#include "gui/gui.hpp"
#include "adbbu/libtwadbbu.hpp"
#ifdef TW_INCLUDE_CRYPTO
	#include "crypto/fde/cryptfs.h"
	#include "Decrypt.h"
#else
	#define CRYPT_FOOTER_OFFSET 0x4000
#endif
extern "C" {
	#include "mtdutils/mtdutils.h"
	#include "mtdutils/mounts.h"
#ifdef USE_EXT4
	// #include "make_ext4fs.h" TODO need ifdef for android8
	#include <ext4_utils/make_ext4fs.h>
#endif
#ifdef TW_INCLUDE_CRYPTO
	#include "gpt/gpt.h"
#endif
}
#include <selinux/selinux.h>
#include <selinux/label.h>
#ifdef HAVE_CAPABILITIES
#include <sys/capability.h>
#include <sys/xattr.h>
#include <linux/xattr.h>
#endif
#include <sparse_format.h>
#include "progresstracking.hpp"

using namespace std;

static int auto_index = 0; // v2 fstab allows you to specify a mount point of "auto" with no /. These items are given a mount point of /auto* where * == auto_index

extern struct selabel_handle *selinux_handle;
extern bool datamedia;

struct flag_list {
	const char *name;
	unsigned long flag;
};

const struct flag_list mount_flags[] = {
	{ "noatime",          MS_NOATIME },
	{ "noexec",           MS_NOEXEC },
	{ "nosuid",           MS_NOSUID },
	{ "nodev",            MS_NODEV },
	{ "nodiratime",       MS_NODIRATIME },
	{ "ro",               MS_RDONLY },
	{ "rw",               0 },
	{ "remount",          MS_REMOUNT },
	{ "bind",             MS_BIND },
	{ "rec",              MS_REC },
#ifdef MS_UNBINDABLE
	{ "unbindable",       MS_UNBINDABLE },
#endif
#ifdef MS_PRIVATE
	{ "private",          MS_PRIVATE },
#endif
#ifdef MS_SLAVE
	{ "slave",            MS_SLAVE },
#endif
#ifdef MS_SHARED
	{ "shared",           MS_SHARED },
#endif
	{ "sync",             MS_SYNCHRONOUS },
	{ 0,                  0 },
};

const char *ignored_mount_items[] = {
	"defaults=",
	"errors=",
	"latemount",
	"sysfs_path=",
	NULL
};

enum TW_FSTAB_FLAGS {
	TWFLAG_DEFAULTS, // Retain position
	TWFLAG_ANDSEC,
	TWFLAG_BACKUP,
	TWFLAG_BACKUPNAME,
	TWFLAG_BLOCKSIZE,
	TWFLAG_CANBEWIPED,
	TWFLAG_CANENCRYPTBACKUP,
	TWFLAG_DISPLAY,
	TWFLAG_ENCRYPTABLE,
	TWFLAG_FILEENCRYPTION,
	TWFLAG_FLASHIMG,
	TWFLAG_FORCEENCRYPT,
	TWFLAG_FSFLAGS,
	TWFLAG_IGNOREBLKID,
	TWFLAG_LENGTH,
	TWFLAG_MOUNTTODECRYPT,
	TWFLAG_REMOVABLE,
	TWFLAG_SETTINGSSTORAGE,
	TWFLAG_STORAGE,
	TWFLAG_STORAGENAME,
	TWFLAG_SUBPARTITIONOF,
	TWFLAG_SYMLINK,
	TWFLAG_USERDATAENCRYPTBACKUP,
	TWFLAG_USERMRF,
	TWFLAG_WIPEDURINGFACTORYRESET,
	TWFLAG_WIPEINGUI,
	TWFLAG_SLOTSELECT,
	TWFLAG_WAIT,
	TWFLAG_VERIFY,
	TWFLAG_CHECK,
	TWFLAG_ALTDEVICE,
	TWFLAG_NOTRIM,
	TWFLAG_VOLDMANAGED,
	TWFLAG_FORMATTABLE,
	TWFLAG_RESIZE,
	TWFLAG_KEYDIRECTORY,
	TWFLAG_WRAPPEDKEY,
	TWFLAG_ADOPTED_MOUNT_DELAY,
	TWFLAG_DM_USE_ORIGINAL_PATH,
};

/* Flags without a trailing '=' are considered dual format flags and can be
 * written as either 'flagname' or 'flagname=', where the character following
 * the '=' is Y,y,1 for true and false otherwise.
 */
const struct flag_list tw_flags[] = {
	{ "andsec",                 TWFLAG_ANDSEC },
	{ "backup",                 TWFLAG_BACKUP },
	{ "backupname=",            TWFLAG_BACKUPNAME },
	{ "blocksize=",             TWFLAG_BLOCKSIZE },
	{ "canbewiped",             TWFLAG_CANBEWIPED },
	{ "canencryptbackup",       TWFLAG_CANENCRYPTBACKUP },
	{ "defaults",               TWFLAG_DEFAULTS },
	{ "display=",               TWFLAG_DISPLAY },
	{ "encryptable=",           TWFLAG_ENCRYPTABLE },
	{ "fileencryption=",        TWFLAG_FILEENCRYPTION },
	{ "flashimg",               TWFLAG_FLASHIMG },
	{ "forceencrypt=",          TWFLAG_FORCEENCRYPT },
	{ "fsflags=",               TWFLAG_FSFLAGS },
	{ "ignoreblkid",            TWFLAG_IGNOREBLKID },
	{ "length=",                TWFLAG_LENGTH },
	{ "mounttodecrypt",         TWFLAG_MOUNTTODECRYPT },
	{ "removable",              TWFLAG_REMOVABLE },
	{ "settingsstorage",        TWFLAG_SETTINGSSTORAGE },
	{ "storage",                TWFLAG_STORAGE },
	{ "storagename=",           TWFLAG_STORAGENAME },
	{ "subpartitionof=",        TWFLAG_SUBPARTITIONOF },
	{ "symlink=",               TWFLAG_SYMLINK },
	{ "userdataencryptbackup",  TWFLAG_USERDATAENCRYPTBACKUP },
	{ "usermrf",                TWFLAG_USERMRF },
	{ "wipeduringfactoryreset", TWFLAG_WIPEDURINGFACTORYRESET },
	{ "wipeingui",              TWFLAG_WIPEINGUI },
	{ "slotselect",             TWFLAG_SLOTSELECT },
	{ "wait",                   TWFLAG_WAIT },
	{ "verify",                 TWFLAG_VERIFY },
	{ "check",                  TWFLAG_CHECK },
	{ "altdevice",              TWFLAG_ALTDEVICE },
	{ "notrim",                 TWFLAG_NOTRIM },
	{ "voldmanaged=",           TWFLAG_VOLDMANAGED },
	{ "formattable",            TWFLAG_FORMATTABLE },
	{ "resize",                 TWFLAG_RESIZE },
	{ "keydirectory=",          TWFLAG_KEYDIRECTORY },
	{ "wrappedkey",             TWFLAG_WRAPPEDKEY },
	{ "adopted_mount_delay=",   TWFLAG_ADOPTED_MOUNT_DELAY },
	{ "dm_use_original_path",   TWFLAG_DM_USE_ORIGINAL_PATH },
	{ 0,                        0 },
};

TWPartition::TWPartition() {
	Can_Be_Mounted = false;
	Can_Be_Wiped = false;
	Can_Be_Backed_Up = false;
	Use_Rm_Rf = false;
	Wipe_During_Factory_Reset = false;
	Wipe_Available_in_GUI = false;
	Is_SubPartition = false;
	Has_SubPartition = false;
	SubPartition_Of = "";
	Symlink_Path = "";
	Symlink_Mount_Point = "";
	Mount_Point = "";
	Backup_Path = "";
	Wildcard_Block_Device = false;
	Sysfs_Entry = "";
	Actual_Block_Device = "";
	Primary_Block_Device = "";
	Alternate_Block_Device = "";
	Removable = false;
	Is_Present = false;
	Length = 0;
	Size = 0;
	Used = 0;
	Free = 0;
	Backup_Size = 0;
	Can_Be_Encrypted = false;
	Is_Encrypted = false;
	Is_Decrypted = false;
	Is_FBE = false;
	Mount_To_Decrypt = false;
	Decrypted_Block_Device = "";
	Display_Name = "";
	Backup_Display_Name = "";
	Storage_Name = "";
	Backup_Name = "";
	Backup_FileName = "";
	MTD_Name = "";
	Backup_Method = BM_NONE;
	Can_Encrypt_Backup = false;
	Use_Userdata_Encryption = false;
	Has_Data_Media = false;
	Has_Android_Secure = false;
	Is_Storage = false;
	Is_Settings_Storage = false;
	Storage_Path = "";
	Current_File_System = "";
	Fstab_File_System = "";
	Mount_Flags = 0;
	Mount_Options = "";
	Format_Block_Size = 0;
	Ignore_Blkid = false;
	Crypto_Key_Location = "";
	MTP_Storage_ID = 0;
	Can_Flash_Img = false;
	Mount_Read_Only = false;
	Is_Adopted_Storage = false;
	Adopted_GUID = "";
	SlotSelect = false;
	Key_Directory = "";
	Is_Super = false;
	Adopted_Mount_Delay = 0;
	Original_Path = "";
	Use_Original_Path = false;
}

TWPartition::~TWPartition(void) {
	// Do nothing
}

bool TWPartition::Process_Fstab_Line(const char *fstab_line, bool Display_Error, std::map<string, Flags_Map> *twrp_flags) {
	char full_line[MAX_FSTAB_LINE_LENGTH];
	char twflags[MAX_FSTAB_LINE_LENGTH] = "";
	char* ptr;
	int line_len = strlen(fstab_line), index = 0, item_index = 0;
	bool skip = false;
	int fstab_version = 1, mount_point_index = 0, fs_index = 1, block_device_index = 2;
	TWPartition *additional_entry = NULL;
	std::map<string, Flags_Map>::iterator it;

	strlcpy(full_line, fstab_line, sizeof(full_line));

	for (index = 0; index < line_len; index++) {
		if (full_line[index] == 34)
			skip = !skip;
		if (!skip && full_line[index] <= 32)
			full_line[index] = '\0';
	}
	if (line_len < 10)
		return false; // There can't possibly be a valid fstab line that is less than 10 chars
	if (strncmp(fstab_line, "/dev/", strlen("/dev/")) == 0 || strncmp(fstab_line, "/devices/", strlen("/devices/")) == 0) {
		fstab_version = 2;
		block_device_index = 0;
		mount_point_index = 1;
		fs_index = 2;
	}

	Is_Super = PartitionManager.Is_Super_Partition(fstab_line);
	if (Is_Super) {
		block_device_index = 0;
		fstab_version = 2;
		mount_point_index = 1;
		fs_index = 2;
	}

	index = 0;
	while (index < line_len) {
		while (index < line_len && full_line[index] == '\0')
			index++;
		if (index >= line_len)
			continue;
		ptr = full_line + index;
		if (item_index == mount_point_index) {
			Mount_Point = ptr;
			if (fstab_version == 2 && Is_Super == false) {
				additional_entry = PartitionManager.Find_Partition_By_Path(Mount_Point);
				if (additional_entry) {
					LOGINFO("Found an additional entry for '%s'\n", Mount_Point.c_str());
				}
			}
			LOGINFO("Processing '%s'\n", Mount_Point.c_str());
			Backup_Path = Mount_Point;
			Storage_Path = Mount_Point;
			Display_Name = ptr + 1;
			Backup_Display_Name = Display_Name;
			Storage_Name = Display_Name;
			item_index++;
		} else if (item_index == fs_index) {
			// File System
			Fstab_File_System = ptr;
			Current_File_System = ptr;
			item_index++;
		} else if (item_index == block_device_index) {
			// Primary Block Device
			if (Fstab_File_System == "mtd" || Fstab_File_System == "yaffs2") {
				MTD_Name = ptr;
				Find_MTD_Block_Device(MTD_Name);
			} else if (Fstab_File_System == "bml") {
				if (Mount_Point == "/boot")
					MTD_Name = "boot";
				else if (Mount_Point == "/recovery")
					MTD_Name = "recovery";
				Primary_Block_Device = ptr;
				if (*ptr != '/')
					LOGERR("Until we get better BML support, you will have to find and provide the full block device path to the BML devices e.g. /dev/block/bml9 instead of the partition name\n");
			} else if (*ptr != '/') {
				if (!Is_Super) {
					if (Display_Error)
						LOGERR("Invalid block device '%s' in fstab line '%s'", ptr, fstab_line);
					else
						LOGINFO("Invalid block device '%s' in fstab line '%s'", ptr, fstab_line);
					return false;
				}
			} else {
				Primary_Block_Device = ptr;
				Find_Real_Block_Device(Primary_Block_Device, Display_Error);
			}
			item_index++;
		} else if (item_index > 2) {
			if (fstab_version == 2) {
				if (item_index == 3) {
					Process_FS_Flags(ptr);
					if (additional_entry) {
						additional_entry->Save_FS_Flags(Fstab_File_System, Mount_Flags, Mount_Options);
						return false; // We save the extra fs flags in the other partition entry and by returning false, this entry will be deleted
					}
				} else {
					strlcpy(twflags, ptr, sizeof(twflags));
				}
				item_index++;
			} else if (*ptr == '/') { // v2 fstab does not allow alternate block devices
				// Alternate Block Device
				Alternate_Block_Device = ptr;
				Find_Real_Block_Device(Alternate_Block_Device, Display_Error);
			} else if (strlen(ptr) > 7 && strncmp(ptr, "length=", 7) == 0) {
				// Partition length
				ptr += 7;
				Length = atoi(ptr);
			} else if (strlen(ptr) > 6 && strncmp(ptr, "flags=", 6) == 0) {
				// Custom flags, save for later so that new values aren't overwritten by defaults
				ptr += 6;
				strlcpy(twflags, ptr, sizeof(twflags));
			} 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
				LOGINFO("Unhandled fstab information '%s' in fstab line '%s'\n", ptr, fstab_line);
			}
		}
		while (index < line_len && full_line[index] != '\0')
			index++;
	}

	// override block devices from the v2 fstab with the ones we read from the twrp.flags file in case they are different
	if (fstab_version == 2 && twrp_flags && twrp_flags->size() > 0) {
		it = twrp_flags->find(Mount_Point);
		if (it != twrp_flags->end()) {
			if (!it->second.Primary_Block_Device.empty()) {
				Primary_Block_Device = it->second.Primary_Block_Device;
				Find_Real_Block_Device(Primary_Block_Device, Display_Error);
			}
			if (!it->second.Alternate_Block_Device.empty()) {
				Alternate_Block_Device = it->second.Alternate_Block_Device;
				Find_Real_Block_Device(Alternate_Block_Device, Display_Error);
			}
		}
	}

	if (strncmp(fstab_line, "/devices/", strlen("/devices/")) == 0) {
		Sysfs_Entry = Primary_Block_Device;
		Primary_Block_Device = "";
		Is_Storage = true;
		Removable = true;
		Wipe_Available_in_GUI = true;
		Wildcard_Block_Device = true;
	}
	if (Primary_Block_Device.find("*") != string::npos)
		Wildcard_Block_Device = true;

	if (Mount_Point == "auto") {
		Mount_Point = "/auto";
		char autoi[5];
		sprintf(autoi, "%i", auto_index);
		Mount_Point += autoi;
		Backup_Path = Mount_Point;
		Storage_Path = Mount_Point;
		Backup_Name = Mount_Point.substr(1);
		auto_index++;
		Setup_File_System(Display_Error);
		Display_Name = "Storage";
		Backup_Display_Name = Display_Name;
		Storage_Name = Display_Name;
		Can_Be_Backed_Up = false;
		Wipe_Available_in_GUI = true;
		Is_Storage = true;
		Removable = true;
		Wipe_Available_in_GUI = true;
	} else if (!Is_File_System(Fstab_File_System) && !Is_Image(Fstab_File_System)) {
		if (Display_Error)
			LOGERR("Unknown File System: '%s'\n", Fstab_File_System.c_str());
		else
			LOGINFO("Unknown File System: '%s'\n", Fstab_File_System.c_str());
		return false;
	} else if (Is_File_System(Fstab_File_System)) {
		Find_Actual_Block_Device();
		Setup_File_System(Display_Error);
		Backup_Name = Display_Name = Mount_Point.substr(1, Mount_Point.size() - 1);
		if (Mount_Point == "/" || Mount_Point == "/system" || Mount_Point == "/system_root") {
			Mount_Point = PartitionManager.Get_Android_Root_Path();
			Backup_Path = Mount_Point;
			Storage_Path = Mount_Point;
			Display_Name = "System";
			Backup_Name = "system";
			Backup_Display_Name = Display_Name;
			Storage_Name = Display_Name;
			Wipe_Available_in_GUI = false;
			Can_Be_Backed_Up = false;
			Can_Be_Wiped = false;
			Mount_Read_Only = true;
			Make_Dir(PartitionManager.Get_Android_Root_Path(), true);
		} else if (Mount_Point == "/product") {
			Display_Name = "Product";
			Backup_Name = "Product";
			Backup_Display_Name = Display_Name;
			Storage_Name = Display_Name;
			Can_Be_Backed_Up = Wipe_Available_in_GUI = Is_Super ? false : true;
			Mount_Read_Only = true;
		} else if (Mount_Point == "/odm") {
			Display_Name = "ODM";
			Backup_Name = "ODM";
			Backup_Display_Name = Display_Name;
			Storage_Name = Display_Name;
			Can_Be_Backed_Up = Wipe_Available_in_GUI = Is_Super ? false : true;
			Mount_Read_Only = true;
		} else if (Mount_Point == "/data") {
			Display_Name = "Data";
			Backup_Display_Name = Display_Name;
			Storage_Name = Display_Name;
			Wipe_Available_in_GUI = true;
			Wipe_During_Factory_Reset = true;
			Can_Be_Backed_Up = true;
			Can_Encrypt_Backup = true;
			Use_Userdata_Encryption = true;
		} else if (Mount_Point == "/cache") {
			Display_Name = "Cache";
			Backup_Display_Name = Display_Name;
			Storage_Name = Display_Name;
			Wipe_Available_in_GUI = true;
			Wipe_During_Factory_Reset = true;
			Can_Be_Backed_Up = true;
		} else if (Mount_Point == "/datadata") {
			Wipe_During_Factory_Reset = true;
			Display_Name = "DataData";
			Backup_Display_Name = Display_Name;
			Storage_Name = Display_Name;
			Is_SubPartition = true;
			SubPartition_Of = "/data";
			DataManager::SetValue(TW_HAS_DATADATA, 1);
			Can_Be_Backed_Up = true;
			Can_Encrypt_Backup = true;
			Use_Userdata_Encryption = false; // This whole partition should be encrypted
		} else if (Mount_Point == "/sd-ext") {
			Wipe_During_Factory_Reset = true;
			Display_Name = "SD-Ext";
			Backup_Display_Name = Display_Name;
			Storage_Name = Display_Name;
			Wipe_Available_in_GUI = true;
			Removable = true;
			Can_Be_Backed_Up = true;
			Can_Encrypt_Backup = true;
			Use_Userdata_Encryption = true;
		} else if (Mount_Point == "/boot") {
			Display_Name = "Boot";
			Backup_Display_Name = Display_Name;
			DataManager::SetValue("tw_boot_is_mountable", 1);
			Can_Be_Backed_Up = true;
		} else if (Mount_Point == "/vendor") {
			Display_Name = "Vendor";
			Backup_Display_Name = Display_Name;
			Storage_Name = Display_Name;
			Mount_Read_Only = true;
		}
#ifdef TW_EXTERNAL_STORAGE_PATH
		if (Mount_Point == EXPAND(TW_EXTERNAL_STORAGE_PATH)) {
			Is_Storage = true;
			Storage_Path = EXPAND(TW_EXTERNAL_STORAGE_PATH);
			Removable = true;
			Wipe_Available_in_GUI = true;
#else
		if (Mount_Point == "/sdcard" || Mount_Point == "/external_sd" || Mount_Point == "/external_sdcard") {
			Is_Storage = true;
			Removable = true;
			Wipe_Available_in_GUI = true;
#endif
		}
#ifdef TW_INTERNAL_STORAGE_PATH
		if (Mount_Point == EXPAND(TW_INTERNAL_STORAGE_PATH)) {
			Is_Storage = true;
			Is_Settings_Storage = true;
			Storage_Path = EXPAND(TW_INTERNAL_STORAGE_PATH);
			Wipe_Available_in_GUI = true;
		}
#else
		if (Mount_Point == "/emmc" || Mount_Point == "/internal_sd" || Mount_Point == "/internal_sdcard") {
			Is_Storage = true;
			Is_Settings_Storage = true;
			Wipe_Available_in_GUI = true;
		}
#endif
	} else if (Is_Image(Fstab_File_System)) {
		Find_Actual_Block_Device();
		Setup_Image();
		if (Mount_Point == "/boot") {
			Display_Name = "Boot";
			Backup_Display_Name = Display_Name;
			Can_Be_Backed_Up = true;
			Can_Flash_Img = true;
		} else if (Mount_Point == "/recovery") {
			Display_Name = "Recovery";
			Backup_Display_Name = Display_Name;
			Can_Flash_Img = true;
		} else if (Mount_Point == "/system_image") {
			Display_Name = "System Image";
			Backup_Display_Name = Display_Name;
			Can_Flash_Img = true;
			Can_Be_Backed_Up = true;
		} else if (Mount_Point == "/vendor_image") {
			Display_Name = "Vendor Image";
			Backup_Display_Name = Display_Name;
			Can_Flash_Img = true;
			Can_Be_Backed_Up = true;
		}
	}

	// Process TWRP fstab flags
	if (strlen(twflags) > 0) {
		string Prev_Display_Name = Display_Name;
		string Prev_Storage_Name = Storage_Name;
		string Prev_Backup_Display_Name = Backup_Display_Name;
		Display_Name = "";
		Storage_Name = "";
		Backup_Display_Name = "";

		Process_TW_Flags(twflags, (fstab_version == 1), fstab_version);
		Save_FS_Flags(Fstab_File_System, Mount_Flags, Mount_Options);

		bool has_display_name = !Display_Name.empty();
		bool has_storage_name = !Storage_Name.empty();
		bool has_backup_name = !Backup_Display_Name.empty();
		if (!has_display_name) Display_Name = Prev_Display_Name;
		if (!has_storage_name) Storage_Name = Prev_Storage_Name;
		if (!has_backup_name) Backup_Display_Name = Prev_Backup_Display_Name;

		if (has_display_name && !has_storage_name)
			Storage_Name = Display_Name;
		if (!has_display_name && has_storage_name)
			Display_Name = Storage_Name;
		if (has_display_name && !has_backup_name && Backup_Display_Name != "Android Secure")
			Backup_Display_Name = Display_Name;
		if (!has_display_name && has_backup_name)
			Display_Name = Backup_Display_Name;
	}

	if (fstab_version == 2 && twrp_flags && twrp_flags->size() > 0) {
		it = twrp_flags->find(Mount_Point);
		if (it != twrp_flags->end()) {
			char twrpflags[MAX_FSTAB_LINE_LENGTH] = "";
			int skip = 0;
			string Flags = it->second.Flags;
			strcpy(twrpflags, Flags.c_str());
			if (strlen(twrpflags) > strlen("flags=") && strncmp(twrpflags, "flags=", strlen("flags=")) == 0)
				skip += strlen("flags=");
			char* flagptr = twrpflags;
			flagptr += skip;
			Process_TW_Flags(flagptr, Display_Error, 1); // Forcing the fstab to ver 1 because this data is coming from the /etc/twrp.flags which should be using the TWRP v1 flags format
		}
	}

	if (Mount_Point == "/persist" && Can_Be_Mounted) {
		bool mounted = Is_Mounted();
		if (mounted || Mount(false)) {
			TWFunc::Fixup_Time_On_Boot("/persist/time/");
			if (!mounted)
				UnMount(false);
		}
	}

	return true;
}

void TWPartition::Partition_Post_Processing(bool Display_Error) {
	if (Mount_Point == "/data")
		Setup_Data_Partition(Display_Error);
	else if (Mount_Point == "/cache")
		Setup_Cache_Partition(Display_Error);
}

void TWPartition::ExcludeAll(const string& path) {
	backup_exclusions.add_absolute_dir(path);
	wipe_exclusions.add_absolute_dir(path);
}

void TWPartition::Setup_Data_Partition(bool Display_Error) {
	if (Mount_Point != "/data")
		return;

	// Ensure /data is not mounted as tmpfs for qcom hardware decrypt
	UnMount(false);

#ifdef TW_INCLUDE_CRYPTO
	if (datamedia)
		Setup_Data_Media();
	Can_Be_Encrypted = true;
	char crypto_blkdev[255];
	property_get("ro.crypto.fs_crypto_blkdev", crypto_blkdev, "error");
	if (strcmp(crypto_blkdev, "error") != 0) {
		Set_FBE_Status();
		Decrypted_Block_Device = crypto_blkdev;
		LOGINFO("Data already decrypted, new block device: '%s'\n", crypto_blkdev);
		DataManager::SetValue(TW_IS_ENCRYPTED, 0);
	} else if (!Mount(false)) {
		if (Is_Present) {
			if (Key_Directory.empty()) {
				set_partition_data(Use_Original_Path ? Original_Path.c_str() : Actual_Block_Device.c_str(), Crypto_Key_Location.c_str(),
				Fstab_File_System.c_str());
				if (cryptfs_check_footer() == 0) {
					Is_Encrypted = true;
					Is_Decrypted = false;
					Can_Be_Mounted = false;
					Current_File_System = "emmc";
					Setup_Image();
					DataManager::SetValue(TW_CRYPTO_PWTYPE, cryptfs_get_password_type());
					DataManager::SetValue("tw_crypto_pwtype_0", cryptfs_get_password_type());
					DataManager::SetValue(TW_CRYPTO_PASSWORD, "");
					DataManager::SetValue("tw_crypto_display", "");
				} else {
					gui_err("mount_data_footer=Could not mount /data and unable to find crypto footer.");
				}
			} else {
				Is_Encrypted = true;
				Is_Decrypted = false;
			}
		} else if (Key_Directory.empty()) {
			LOGERR("Primary block device '%s' for mount point '%s' is not present!\n",
			Primary_Block_Device.c_str(), Mount_Point.c_str());
		}
	} else {
		Set_FBE_Status();
		int is_device_fbe;
		DataManager::GetValue(TW_IS_FBE, is_device_fbe);
		if (!Decrypt_FBE_DE() && is_device_fbe == 1) {
			char wrappedvalue[PROPERTY_VALUE_MAX];
			property_get("fbe.data.wrappedkey", wrappedvalue, "");
			std::string wrappedkeyvalue(wrappedvalue);
			if (wrappedkeyvalue == "true") {
				LOGERR("Unable to decrypt FBE device\n");
			} else {
				LOGINFO("Trying wrapped key.\n");
				property_set("fbe.data.wrappedkey", "true");
				if (!Decrypt_FBE_DE()) {
					LOGERR("Unable to decrypt FBE device\n");
				}
			}
		}
		DataManager::SetValue(TW_IS_ENCRYPTED, 0);
	}
	if (datamedia && (!Is_Encrypted || (Is_Encrypted && Is_Decrypted))) {
		Setup_Data_Media();
		Recreate_Media_Folder();
	}
#else
	if (datamedia) {
		Setup_Data_Media();
		Recreate_Media_Folder();
	}
#endif
}

void TWPartition::Set_FBE_Status() {
	DataManager::SetValue(TW_IS_DECRYPTED, 1);
	Is_Encrypted = true;
	Is_Decrypted = true;
	if (Key_Directory.empty()) {
		Is_FBE = false;
		DataManager::SetValue(TW_IS_FBE, 0);
	} else {
		LOGINFO("Setup_Data_Partition::Key_Directory::%s\n", Key_Directory.c_str());
		Is_FBE = true;
		DataManager::SetValue(TW_IS_FBE, 1);
	}
}

bool TWPartition::Decrypt_FBE_DE() {
	if (TWFunc::Path_Exists("/data/unencrypted/key/version")) {
		DataManager::SetValue(TW_IS_FBE, 1);
		DataManager::SetValue(TW_CRYPTO_PWTYPE, "0"); // Set initial value so that recovery will not be confused when using unencrypted data or failed to decrypt data
		property_set("ro.crypto.state", "encrypted");
		property_set("ro.crypto.type", "file");
		LOGINFO("File Based Encryption is present\n");
#ifdef TW_INCLUDE_FBE
	Is_FBE = true;
	ExcludeAll(Mount_Point + "/convert_fbe");
	ExcludeAll(Mount_Point + "/unencrypted");
	ExcludeAll(Mount_Point + "/misc/vold/user_keys");
	ExcludeAll(Mount_Point + "/misc/vold/volume_keys");
	ExcludeAll(Mount_Point + "/system/gatekeeper.password.key");
	ExcludeAll(Mount_Point + "/system/gatekeeper.pattern.key");
	ExcludeAll(Mount_Point + "/system/locksettings.db");
	ExcludeAll(Mount_Point + "/system/locksettings.db-wal");
	ExcludeAll(Mount_Point + "/misc/gatekeeper");
	ExcludeAll(Mount_Point + "/misc/keystore");
	ExcludeAll(Mount_Point + "/drm/kek.dat");
	ExcludeAll(Mount_Point + "/system_de/0/spblob");  // contains data needed to decrypt synthetic password
	// ExcludeAll(Mount_Point + "/system/users/0/gatekeeper.password.key");
	// ExcludeAll(Mount_Point + "/system/users/0/gatekeeper.pattern.key");
	ExcludeAll(Mount_Point + "/cache");
	ExcludeAll(Mount_Point + "/system/users/0");
	ExcludeAll(Mount_Point + "/per_boot"); // removed each boot by init
	ExcludeAll(Mount_Point + "/gsi"); // cow devices

	int retry_count = 3;
	while (!Decrypt_DE() && --retry_count)
		usleep(2000);
	if (retry_count > 0) {
		property_set("ro.crypto.state", "encrypted");
		Is_Encrypted = true;
		Is_Decrypted = false;
		DataManager::SetValue(TW_IS_ENCRYPTED, 1);
		string filename;
		int pwd_type = Get_Password_Type(0, filename);
		if (pwd_type < 0) {
			LOGERR("This TWRP does not have synthetic password decrypt support\n");
			pwd_type = 0;  // default password
		}
		PartitionManager.Parse_Users();  // after load_all_de_keys() to parse_users
		std::vector<users_struct>::iterator iter;
		std::vector<users_struct>* userList = PartitionManager.Get_Users_List();
		for (iter = userList->begin(); iter != userList->end(); iter++) {
			if (atoi((*iter).userId.c_str()) != 0) {
				ExcludeAll(Mount_Point + "/system_de/" + (*iter).userId + "/spblob");
				ExcludeAll(Mount_Point + "/system/users/" + (*iter).userId + "/gatekeeper.password.key");
				ExcludeAll(Mount_Point + "/system/users/" + (*iter).userId + "/gatekeeper.pattern.key");
				ExcludeAll(Mount_Point + "/system/users/" + (*iter).userId + "/locksettings.db");
				ExcludeAll(Mount_Point + "/system/users/" + (*iter).userId + "/locksettings.db-wal");
			}
		}
		DataManager::SetValue(TW_CRYPTO_PWTYPE, pwd_type);
		DataManager::SetValue("tw_crypto_pwtype_0", pwd_type);
		DataManager::SetValue(TW_CRYPTO_PASSWORD, "");
		DataManager::SetValue("tw_crypto_display", "");
		return true;
	}
#else
		LOGERR("FBE found but FBE support not present in TWRP\n");
#endif
	}
	DataManager::SetValue(TW_IS_FBE, 0);
	return false;
}

void TWPartition::Setup_Cache_Partition(bool Display_Error __unused) {
	if (Mount_Point != "/cache")
		return;

	if (!Mount(true))
		return;

	if (!TWFunc::Path_Exists("/cache/recovery/.")) {
		LOGINFO("Recreating /cache/recovery folder\n");
		if (mkdir("/cache/recovery", S_IRWXU | S_IRWXG | S_IWGRP | S_IXGRP) != 0)
			LOGERR("Could not create /cache/recovery\n");
	}
}

void TWPartition::Process_FS_Flags(const char *str) {
	char *options = strdup(str);
	char *ptr, *savep;

	Mount_Options = "";

	// Avoid issues with potentially nested strtok by using strtok_r
	for (ptr = strtok_r(options, ",", &savep); ptr; ptr = strtok_r(NULL, ",", &savep)) {
		char *equals = strstr(ptr, "=");
		size_t name_len;

		if (!equals)
			name_len = strlen(ptr);
		else
			name_len = equals - ptr;

		// There are some flags that we want to ignore in TWRP
		bool found_match = false;
		for (const char** ignored_mount_item = ignored_mount_items; *ignored_mount_item; ignored_mount_item++) {
			if (strncmp(ptr, *ignored_mount_item, name_len) == 0) {
				found_match = true;
				break;
			}
		}
		if (found_match)
			continue;

		// mount_flags are never postfixed by '='
		if (!equals) {
			const struct flag_list* mount_flag = mount_flags;
			for (; mount_flag->name; mount_flag++) {
				if (strcmp(ptr, mount_flag->name) == 0) {
					if (mount_flag->flag == MS_RDONLY)
						Mount_Read_Only = true;
					else
						Mount_Flags |= (unsigned)mount_flag->flag;
					found_match = true;
					break;
				}
			}
			if (found_match)
				continue;
		}

		// If we aren't ignoring this flag and it's not a mount flag, then it must be a mount option
		if (!Mount_Options.empty())
			Mount_Options += ",";
		Mount_Options += ptr;
	}
	free(options);
}

void TWPartition::Save_FS_Flags(const string& local_File_System, int local_Mount_Flags, const string& local_Mount_Options) {
	partition_fs_flags_struct flags;
	flags.File_System = local_File_System;
	flags.Mount_Flags = local_Mount_Flags;
	flags.Mount_Options = local_Mount_Options;
	fs_flags.push_back(flags);
}

void TWPartition::Apply_TW_Flag(const unsigned flag, const char* str, const bool val) {
	switch (flag) {
		case TWFLAG_ANDSEC:
			Has_Android_Secure = val;
			break;
		case TWFLAG_BACKUP:
			Can_Be_Backed_Up = val;
			break;
		case TWFLAG_BACKUPNAME:
			Backup_Display_Name = str;
			break;
		case TWFLAG_BLOCKSIZE:
			Format_Block_Size = (unsigned long)(atol(str));
			break;
		case TWFLAG_CANBEWIPED:
			Can_Be_Wiped = val;
			break;
		case TWFLAG_CANENCRYPTBACKUP:
			Can_Encrypt_Backup = val;
			break;
		case TWFLAG_DEFAULTS:
		case TWFLAG_WAIT:
		case TWFLAG_VERIFY:
		case TWFLAG_CHECK:
		case TWFLAG_NOTRIM:
		case TWFLAG_VOLDMANAGED:
		case TWFLAG_RESIZE:
			// Do nothing
			break;
		case TWFLAG_DISPLAY:
			Display_Name = str;
			break;
		case TWFLAG_ENCRYPTABLE:
		case TWFLAG_FORCEENCRYPT:
			Crypto_Key_Location = str;
			break;
		case TWFLAG_FILEENCRYPTION:
			// This flag isn't used by TWRP but is needed in 9.0 FBE decrypt
			// fileencryption=ice:aes-256-heh
			{
				std::string FBE = str;
				size_t colon_loc = FBE.find(":");
				if (colon_loc == std::string::npos) {
					property_set("fbe.contents", FBE.c_str());
					property_set("fbe.filenames", "");
					LOGINFO("FBE contents '%s', filenames ''\n", FBE.c_str());
					break;
				}
				std::string FBE_contents, FBE_filenames;
				FBE_contents = FBE.substr(0, colon_loc);
				FBE_filenames = FBE.substr(colon_loc + 1);
				property_set("fbe.contents", FBE_contents.c_str());
				property_set("fbe.filenames", FBE_filenames.c_str());
				LOGINFO("FBE contents '%s', filenames '%s'\n", FBE_contents.c_str(), FBE_filenames.c_str());
			}
			break;
		case TWFLAG_WRAPPEDKEY:
			// Set wrappedkey props to true for data and/or metadata
			{
				size_t slash_loc = Mount_Point.find('/');
				std::string partition = Mount_Point.substr(slash_loc + 1);
				if (Mount_Point == "/data" || Mount_Point == "/metadata") {
					std::string wrapped_prop = "fbe." + partition + ".wrappedkey";
					property_set(wrapped_prop.c_str(), "true");
					LOGINFO("FBE wrapped key enabled for %s\n", Mount_Point.c_str());
				}
			}
			break;
		case TWFLAG_FLASHIMG:
			Can_Flash_Img = val;
			break;
		case TWFLAG_FSFLAGS:
			Process_FS_Flags(str);
			break;
		case TWFLAG_IGNOREBLKID:
			Ignore_Blkid = val;
			break;
		case TWFLAG_LENGTH:
			Length = atoi(str);
			break;
		case TWFLAG_MOUNTTODECRYPT:
			Mount_To_Decrypt = val;
			break;
		case TWFLAG_REMOVABLE:
			Removable = val;
			break;
		case TWFLAG_SETTINGSSTORAGE:
			Is_Settings_Storage = val;
			if (Is_Settings_Storage)
				Is_Storage = true;
			break;
		case TWFLAG_STORAGE:
			Is_Storage = val;
			break;
		case TWFLAG_STORAGENAME:
			Storage_Name = str;
			break;
		case TWFLAG_SUBPARTITIONOF:
			Is_SubPartition = true;
			SubPartition_Of = str;
			break;
		case TWFLAG_SYMLINK:
			Symlink_Path = str;
			break;
		case TWFLAG_USERDATAENCRYPTBACKUP:
			Use_Userdata_Encryption = val;
			if (Use_Userdata_Encryption)
				Can_Encrypt_Backup = true;
			break;
		case TWFLAG_USERMRF:
			Use_Rm_Rf = val;
			break;
		case TWFLAG_WIPEDURINGFACTORYRESET:
			Wipe_During_Factory_Reset = val;
			if (Wipe_During_Factory_Reset) {
				Can_Be_Wiped = true;
				Wipe_Available_in_GUI = true;
			}
			break;
		case TWFLAG_WIPEINGUI:
		case TWFLAG_FORMATTABLE:
			Wipe_Available_in_GUI = val;
			if (Wipe_Available_in_GUI)
				Can_Be_Wiped = true;
			break;
		case TWFLAG_SLOTSELECT:
			SlotSelect = true;
			break;
		case TWFLAG_ALTDEVICE:
			Alternate_Block_Device = str;
			break;
		case TWFLAG_ADOPTED_MOUNT_DELAY:
			Adopted_Mount_Delay = atoi(str);
			break;
		case TWFLAG_KEYDIRECTORY:
			Key_Directory = str;
			LOGINFO("setting Key_Directory to: %s\n", Key_Directory.c_str());
			break;
		case TWFLAG_DM_USE_ORIGINAL_PATH:
			Use_Original_Path = true;
			break;
		default:
			// Should not get here
			LOGINFO("Flag identified for processing, but later unmatched: %i\n", flag);
			break;
	}
}

void TWPartition::Process_TW_Flags(char *flags, bool Display_Error, int fstab_ver) {
	char separator[2] = {'\n', 0};
	char *ptr, *savep;
	char source_separator = ';';

	if (fstab_ver == 2)
		source_separator = ',';

	// Semicolons within double-quotes are not forbidden, so replace
	// only the semicolons intended as separators with '\n' for strtok
	for (unsigned i = 0, skip = 0; i < strlen(flags); i++) {
		if (flags[i] == '\"')
			skip = !skip;
		if (!skip && flags[i] == source_separator)
			flags[i] = separator[0];
	}

	// Avoid issues with potentially nested strtok by using strtok_r
	ptr = strtok_r(flags, separator, &savep);
	while (ptr) {
		int ptr_len = strlen(ptr);
		const struct flag_list* tw_flag = tw_flags;

		for (; tw_flag->name; tw_flag++) {
			int flag_len = strlen(tw_flag->name);

			if (strncmp(ptr, tw_flag->name, flag_len) == 0) {
				bool flag_val = false;

				if (ptr_len > flag_len && (tw_flag->name)[flag_len-1] != '='
						&& ptr[flag_len] != '=') {
					// Handle flags with same starting string
					// (e.g. backup and backupname)
					continue;
				} else if (ptr_len > flag_len && ptr[flag_len] == '=') {
					// Handle flags with dual format: Part 1
					// (e.g. backup and backup=y. backup=y handled here)
					ptr += flag_len + 1;
					TWFunc::Strip_Quotes(ptr);
					// Skip flags with empty argument
					// (e.g. backup=)
					if (strlen(ptr) == 0) {
						LOGINFO("Flag missing argument or should not include '=': %s=\n", tw_flag->name);
						break;
					}
					flag_val = strchr("yY1", *ptr) != NULL;
				} else if (ptr_len == flag_len
						&& (tw_flag->name)[flag_len-1] == '=') {
					// Skip flags missing argument after =
					// (e.g. backupname=)
					LOGINFO("Flag missing argument: %s\n", tw_flag->name);
					break;
				} else if (ptr_len > flag_len
						&& (tw_flag->name)[flag_len-1] == '=') {
					// Handle arguments to flags
					// (e.g. backupname="My Stuff")
					ptr += flag_len;
					TWFunc::Strip_Quotes(ptr);
					// Skip flags with empty argument
					// (e.g. backupname="")
					if (strlen(ptr) == 0) {
						LOGINFO("Flag missing argument: %s\n", tw_flag->name);
						break;
					}
				} else if (ptr_len == flag_len) {
					// Handle flags with dual format: Part 2
					// (e.g. backup and backup=y. backup handled here)
					flag_val = true;
				} else {
					LOGINFO("Flag matched, but could not be processed: %s\n", ptr);
					break;
				}

				Apply_TW_Flag(tw_flag->flag, ptr, flag_val);
				break;
			}
		}
		if (tw_flag->name == 0) {
			if (Display_Error)
				LOGERR("Unhandled flag: '%s'\n", ptr);
			else
				LOGINFO("Unhandled flag: '%s'\n", ptr);
		}
		ptr = strtok_r(NULL, separator, &savep);
	}
}

bool TWPartition::Is_File_System(string File_System) {
	if (File_System == "ext2" ||
		File_System == "ext3" ||
		File_System == "ext4" ||
		File_System == "vfat" ||
		File_System == "ntfs" ||
		File_System == "yaffs2" ||
		File_System == "exfat" ||
		File_System == "f2fs" ||
		File_System == "squashfs" ||
		File_System == "auto")
		return true;
	else
		return false;
}

bool TWPartition::Is_Image(string File_System) {
	if (File_System == "emmc" || File_System == "mtd" || File_System == "bml")
		return true;
	else
		return false;
}

bool TWPartition::Make_Dir(string Path, bool Display_Error) {
	if (TWFunc::Get_D_Type_From_Stat(Path) != S_IFDIR)
		unlink(Path.c_str());
	if (!TWFunc::Path_Exists(Path)) {
		if (mkdir(Path.c_str(), 0777) == -1) {
			if (Display_Error)
				gui_msg(Msg(msg::kError, "create_folder_strerr=Can not create '{1}' folder ({2}).")(Path)(strerror(errno)));
			else
				LOGINFO("Can not create '%s' folder.\n", Path.c_str());
			return false;
		} else {
			LOGINFO("Created '%s' folder.\n", Path.c_str());
			return true;
		}
	}
	return true;
}

void TWPartition::Setup_File_System(bool Display_Error) {
	Can_Be_Mounted = true;
	Can_Be_Wiped = true;

	// Make the mount point folder if it doesn't exist
	Make_Dir(Mount_Point, Display_Error);
	Backup_Method = BM_FILES;
}

void TWPartition::Setup_Image() {
	Display_Name = Mount_Point.substr(1, Mount_Point.size() - 1);
	Backup_Name = Display_Name;
	if (Current_File_System == "emmc")
		Backup_Method = BM_DD;
	else if (Current_File_System == "mtd" || Current_File_System == "bml")
		Backup_Method = BM_FLASH_UTILS;
	else
		LOGINFO("Unhandled file system '%s' on image '%s'\n", Current_File_System.c_str(), Display_Name.c_str());
}

void TWPartition::Setup_AndSec(void) {
	Backup_Display_Name = "Android Secure";
	Backup_Name = "and-sec";
	Can_Be_Backed_Up = true;
	Has_Android_Secure = true;
	Symlink_Path = Mount_Point + "/.android_secure";
	Symlink_Mount_Point = "/and-sec";
	Backup_Path = Symlink_Mount_Point;
	Make_Dir("/and-sec", true);
	Recreate_AndSec_Folder();
	Mount_Storage_Retry(true);
}

void TWPartition::Setup_Data_Media() {
	LOGINFO("Setting up '%s' as data/media emulated storage.\n", Mount_Point.c_str());
	if (Storage_Name.empty() || Storage_Name == "Data")
		Storage_Name = "Internal Storage";
	Has_Data_Media = true;
	Is_Storage = true;
	Storage_Path = Mount_Point + "/media";
	Symlink_Path = Storage_Path;
	if (Mount_Point == "/data") {
		Is_Settings_Storage = true;
		if (strcmp(EXPAND(TW_EXTERNAL_STORAGE_PATH), "/sdcard") == 0) {
			Make_Dir("/emmc", false);
			Symlink_Mount_Point = "/emmc";
		} else {
			Make_Dir("/sdcard", false);
			Symlink_Mount_Point = "/sdcard";
		}
		if (Mount(false) && TWFunc::Path_Exists(Mount_Point + "/media/0")) {
			Storage_Path = Mount_Point + "/media/0";
			Symlink_Path = Storage_Path;
			DataManager::SetValue(TW_INTERNAL_PATH, Mount_Point + "/media/0");
			UnMount(true);
		}
		DataManager::SetValue("tw_has_internal", 1);
		DataManager::SetValue("tw_has_data_media", 1);
		backup_exclusions.add_absolute_dir("/data/data/com.google.android.music/files");
		backup_exclusions.add_absolute_dir("/data/per_boot"); // DJ9,14Jan2020 - exclude this dir to prevent "error 255" on AOSP ROMs that create and lock it
		backup_exclusions.add_absolute_dir("/data/vendor/dumpsys");
		backup_exclusions.add_absolute_dir("/data/cache");
		wipe_exclusions.add_absolute_dir(Mount_Point + "/misc/vold"); // adopted storage keys
		ExcludeAll(Mount_Point + "/system/storage.xml");
	} else {
		if (Mount(true) && TWFunc::Path_Exists(Mount_Point + "/media/0")) {
			Storage_Path = Mount_Point + "/media/0";
			Symlink_Path = Storage_Path;
			UnMount(true);
		}
	}
	ExcludeAll(Mount_Point + "/media");
}

void TWPartition::Find_Real_Block_Device(string& Block, bool Display_Error) {
	char device[PATH_MAX], realDevice[PATH_MAX];

	Original_Path = Block;

	strcpy(device, Block.c_str());
	memset(realDevice, 0, sizeof(realDevice));
	while (readlink(device, realDevice, sizeof(realDevice)) > 0)
	{
		strcpy(device, realDevice);
		memset(realDevice, 0, sizeof(realDevice));
	}

	if (device[0] != '/') {
		if (Display_Error)
			LOGERR("Invalid symlink path '%s' found on block device '%s'\n", device, Block.c_str());
		else
			LOGINFO("Invalid symlink path '%s' found on block device '%s'\n", device, Block.c_str());
		return;
	} else {
		Block = device;
		return;
	}
}

bool TWPartition::Mount_Storage_Retry(bool Display_Error) {
	// On some devices, storage doesn't want to mount right away, retry and sleep
	if (!Mount(Display_Error)) {
		int retry_count = 5;
		while (retry_count > 0 && !Mount(false)) {
			usleep(500000);
			retry_count--;
		}
		return Mount(Display_Error);
	}
	return true;
}

bool TWPartition::Find_MTD_Block_Device(string MTD_Name) {
	FILE *fp = NULL;
	char line[255];

	fp = fopen("/proc/mtd", "rt");
	if (fp == NULL) {
		LOGERR("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;
		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 true;
			}
		}
	}
	fclose(fp);

	return false;
}

bool TWPartition::Get_Size_Via_statfs(bool Display_Error) {
	struct statfs st;
	string Local_Path = Mount_Point + "/.";

	if (!Mount(Display_Error))
		return false;

	if (statfs(Local_Path.c_str(), &st) != 0) {
		if (!Removable) {
			if (Display_Error)
				LOGERR("Unable to statfs '%s'\n", Local_Path.c_str());
			else
				LOGINFO("Unable to statfs '%s'\n", Local_Path.c_str());
		}
		return false;
	}
	Size = (st.f_blocks * st.f_bsize);
	Used = ((st.f_blocks - st.f_bfree) * st.f_bsize);
	Free = (st.f_bfree * st.f_bsize);
	Backup_Size = Used;
	return true;
}

bool TWPartition::Get_Size_Via_df(bool Display_Error) {
	FILE* fp;
	char command[255], line[512];
	int include_block = 1;
	unsigned int min_len;

	if (!Mount(Display_Error))
		return false;

	min_len = Actual_Block_Device.size() + 2;
	sprintf(command, "df %s > /tmp/dfoutput.txt", Mount_Point.c_str());
	TWFunc::Exec_Cmd(command);
	fp = fopen("/tmp/dfoutput.txt", "rt");
	if (fp == NULL) {
		LOGINFO("Unable to open /tmp/dfoutput.txt.\n");
		return false;
	}

	while (fgets(line, sizeof(line), fp) != NULL)
	{
		unsigned long blocks, used, available;
		char device[64];
		char tmpString[64];

		if (strncmp(line, "Filesystem", 10) == 0)
			continue;
		if (strlen(line) < min_len) {
			include_block = 0;
			continue;
		}
		if (include_block) {
			sscanf(line, "%s %lu %lu %lu", device, &blocks, &used, &available);
		} else {
			// The device block string is so long that the df information is on the next line
			int space_count = 0;
			sprintf(tmpString, "/dev/block/%s", Actual_Block_Device.c_str());
			while (tmpString[space_count] == 32)
				space_count++;
			sscanf(line + space_count, "%lu %lu %lu", &blocks, &used, &available);
		}

		// Adjust block size to byte size
		Size = blocks * 1024ULL;
		Used = used * 1024ULL;
		Free = available * 1024ULL;
		Backup_Size = Used;
	}
	fclose(fp);
	return true;
}

unsigned long long TWPartition::IOCTL_Get_Block_Size() {
	Find_Actual_Block_Device();

	return TWFunc::IOCTL_Get_Block_Size(Actual_Block_Device.c_str());
}

bool TWPartition::Find_Partition_Size(void) {
	FILE* fp;
	char line[512];
	string tmpdevice;

	fp = fopen("/proc/dumchar_info", "rt");
	if (fp != NULL) {
		while (fgets(line, sizeof(line), fp) != NULL)
		{
			char label[32], device[32];
			unsigned long size = 0;

			sscanf(line, "%s %lx %*x %*u %s", label, &size, device);

			// Skip header, annotation	and blank lines
			if ((strncmp(device, "/dev/", 5) != 0) || (strlen(line) < 8))
				continue;

			tmpdevice = "/dev/";
			tmpdevice += label;
			if (tmpdevice == Primary_Block_Device || tmpdevice == Alternate_Block_Device) {
				Size = size;
				fclose(fp);
				return true;
			}
		}
	}

	unsigned long long ioctl_size = IOCTL_Get_Block_Size();
	if (ioctl_size) {
		Size = ioctl_size;
		return true;
	}

	// In this case, we'll first get the partitions we care about (with labels)
	fp = fopen("/proc/partitions", "rt");
	if (fp == NULL)
		return false;

	while (fgets(line, sizeof(line), fp) != NULL)
	{
		unsigned long major, minor, blocks;
		char device[512];

		if (strlen(line) < 7 || line[0] == 'm')	 continue;
		sscanf(line + 1, "%lu %lu %lu %s", &major, &minor, &blocks, device);

		tmpdevice = "/dev/block/";
		tmpdevice += device;
		if (tmpdevice == Primary_Block_Device || tmpdevice == Alternate_Block_Device) {
			// Adjust block size to byte size
			Size = blocks * 1024ULL;
			fclose(fp);
			return true;
		}
	}
	fclose(fp);
	return false;
}

bool TWPartition::Is_Mounted(void) {
	if (!Can_Be_Mounted)
		return false;

	struct stat st1, st2;
	string test_path;

	// Check to see if the mount point directory exists
	test_path = Mount_Point + "/.";
	if (stat(test_path.c_str(), &st1) != 0)  return false;

	// Check to see if the directory above the mount point exists
	test_path = Mount_Point + "/../.";
	if (stat(test_path.c_str(), &st2) != 0)  return false;

	// Compare the device IDs -- if they match then we're (probably) using tmpfs instead of an actual device
	int ret = (st1.st_dev != st2.st_dev) ? true : false;
	return ret;
}

bool TWPartition::Is_File_System_Writable(void) {
	if (!Is_File_System(Current_File_System) || !Is_Mounted())
		return false;

	string test_path = Mount_Point + "/.";
	return (access(test_path.c_str(), W_OK) == 0);
}

bool TWPartition::Mount(bool Display_Error) {
	int exfat_mounted = 0;
	unsigned int flags = Mount_Flags;

	if (Is_Mounted()) {
		return true;
	} else if (!Can_Be_Mounted) {
		return false;
	}

	Find_Actual_Block_Device();

	// Check the current file system before mounting
	Check_FS_Type();
	if (Current_File_System == "exfat" && TWFunc::Path_Exists("/system/bin/exfat-fuse")) {
		string cmd = "/system/bin/exfat-fuse -o big_writes,max_read=131072,max_write=131072 " + Actual_Block_Device + " " + Mount_Point;
		LOGINFO("cmd: %s\n", cmd.c_str());
		string result;
		if (TWFunc::Exec_Cmd(cmd, result, false) != 0) {
			LOGINFO("exfat-fuse failed to mount with result '%s', trying vfat\n", result.c_str());
			Current_File_System = "vfat";
		} else {
#ifdef TW_NO_EXFAT_FUSE
			UnMount(false);
			// We'll let the kernel handle it but using exfat-fuse to detect if the file system is actually exfat
			// Some kernels let us mount vfat as exfat which doesn't work out too well
#else
			exfat_mounted = 1;
#endif
		}
	}

	if (Current_File_System == "ntfs" && !TWFunc::Path_Exists("/sys/module/tntfs") && (TWFunc::Path_Exists("/system/bin/ntfs-3g") || TWFunc::Path_Exists("/system/bin/mount.ntfs"))) {
		string cmd;
		string Ntfsmount_Binary = "";

		if (TWFunc::Path_Exists("/system/bin/ntfs-3g"))
			Ntfsmount_Binary = "ntfs-3g";
		else if (TWFunc::Path_Exists("/system/bin/mount.ntfs"))
			Ntfsmount_Binary = "mount.ntfs";

		if (Mount_Read_Only)
			cmd = "/system/bin/" + Ntfsmount_Binary + " -o ro " + Actual_Block_Device + " " + Mount_Point;
		else
			cmd = "/system/bin/" + Ntfsmount_Binary + " " + Actual_Block_Device + " " + Mount_Point;
		LOGINFO("cmd: '%s'\n", cmd.c_str());

		if (TWFunc::Exec_Cmd(cmd) == 0) {
			return true;
		} else {
			LOGINFO("ntfs-3g failed to mount, trying regular mount method.\n");
		}
	} else {
		if (Current_File_System == "ntfs" && TWFunc::Path_Exists("/sys/module/tntfs"))
			Current_File_System = "tntfs";
	}

	if (Mount_Read_Only)
		flags |= MS_RDONLY;

	if (Fstab_File_System == "yaffs2") {
		// mount an MTD partition as a YAFFS2 filesystem.
		flags = MS_NOATIME | MS_NODEV | MS_NODIRATIME;
		if (Mount_Read_Only)
			flags |= MS_RDONLY;
		if (mount(Actual_Block_Device.c_str(), Mount_Point.c_str(), Fstab_File_System.c_str(), flags, NULL) < 0) {
			if (mount(Actual_Block_Device.c_str(), Mount_Point.c_str(), Fstab_File_System.c_str(), flags | MS_RDONLY, NULL) < 0) {
				if (Display_Error)
					gui_msg(Msg(msg::kError, "fail_mount=Failed to mount '{1}' ({2})")(Mount_Point)(strerror(errno)));
				else
					LOGINFO("Failed to mount '%s' (MTD)\n", Mount_Point.c_str());
				return false;
			} else {
				LOGINFO("Mounted '%s' (MTD) as RO\n", Mount_Point.c_str());
				return true;
			}
		} else {
			struct stat st;
			string test_path = Mount_Point;
			if (stat(test_path.c_str(), &st) < 0) {
				if (Display_Error)
					gui_msg(Msg(msg::kError, "fail_mount=Failed to mount '{1}' ({2})")(Mount_Point)(strerror(errno)));
				else
					LOGINFO("Failed to mount '%s' (MTD)\n", Mount_Point.c_str());
				return false;
			}
			mode_t new_mode = st.st_mode | S_IXUSR | S_IXGRP | S_IXOTH;
			if (new_mode != st.st_mode) {
				LOGINFO("Fixing execute permissions for %s\n", Mount_Point.c_str());
				if (chmod(Mount_Point.c_str(), new_mode) < 0) {
					if (Display_Error)
						LOGERR("Couldn't fix permissions for %s: %s\n", Mount_Point.c_str(), strerror(errno));
					else
						LOGINFO("Couldn't fix permissions for %s: %s\n", Mount_Point.c_str(), strerror(errno));
					return false;
				}
			}
			return true;
		}
	}

	string mount_fs = Current_File_System;
	if (Current_File_System == "exfat" && TWFunc::Path_Exists("/sys/module/texfat"))
		mount_fs = "texfat";

	if (!exfat_mounted &&
		mount(Actual_Block_Device.c_str(), Mount_Point.c_str(), mount_fs.c_str(), flags, Mount_Options.c_str()) != 0 &&
		mount(Actual_Block_Device.c_str(), Mount_Point.c_str(), mount_fs.c_str(), flags, NULL) != 0) {
#ifdef TW_NO_EXFAT_FUSE
		if (Current_File_System == "exfat") {
			LOGINFO("Mounting exfat failed, trying vfat...\n");
			if (mount(Actual_Block_Device.c_str(), Mount_Point.c_str(), "vfat", 0, NULL) != 0) {
				if (Display_Error)
					gui_msg(Msg(msg::kError, "fail_mount=Failed to mount '{1}' ({2})")(Mount_Point)(strerror(errno)));
				else
					LOGINFO("Unable to mount '%s'\n", Mount_Point.c_str());
				LOGINFO("Actual block device: '%s', current file system: '%s', flags: 0x%8x, options: '%s'\n", Actual_Block_Device.c_str(), Current_File_System.c_str(), flags, Mount_Options.c_str());
				return false;
			}
		} else {
#endif
			if (!Removable && Display_Error)
				gui_msg(Msg(msg::kError, "fail_mount=Failed to mount '{1}' ({2})")(Mount_Point)(strerror(errno)));
			else
				LOGINFO("Unable to mount '%s'\n", Mount_Point.c_str());
			LOGINFO("Actual block device: '%s', current file system: '%s'\n", Actual_Block_Device.c_str(), Current_File_System.c_str());
			return false;
#ifdef TW_NO_EXFAT_FUSE
		}
#endif
	}

	if (Removable)
		Update_Size(Display_Error);

	if (!Symlink_Mount_Point.empty()) {
		if (!Bind_Mount(false))
			return false;
	}
	return true;
}

bool TWPartition::Bind_Mount(bool Display_Error) {
	if (TWFunc::Path_Exists(Symlink_Path)) {
		if (mount(Symlink_Path.c_str(), Symlink_Mount_Point.c_str(), "", MS_BIND, NULL) < 0) {
			return false;
		}
	}
	return true;
}

bool TWPartition::UnMount(bool Display_Error) {
	if (Is_Mounted()) {
		int never_unmount_system;

		DataManager::GetValue(TW_DONT_UNMOUNT_SYSTEM, never_unmount_system);
		if (never_unmount_system == 1 && Mount_Point == PartitionManager.Get_Android_Root_Path())
			return true; // Never unmount system if you're not supposed to unmount it

		if (Is_Storage && MTP_Storage_ID > 0)
			PartitionManager.Remove_MTP_Storage(MTP_Storage_ID);

		if (!Symlink_Mount_Point.empty())
			umount(Symlink_Mount_Point.c_str());

		umount(Mount_Point.c_str());
		if (Is_Mounted()) {
			if (Display_Error)
				gui_msg(Msg(msg::kError, "fail_unmount=Failed to unmount '{1}' ({2})")(Mount_Point)(strerror(errno)));
			else
				LOGINFO("Unable to unmount '%s'\n", Mount_Point.c_str());
			return false;
		} else {
			return true;
		}
	} else {
		return true;
	}
}

bool TWPartition::ReMount(bool Display_Error) {
	if (UnMount(Display_Error))
		return Mount(Display_Error);
	return false;
}

bool TWPartition::ReMount_RW(bool Display_Error) {
	// No need to remount if already mounted rw
	if (Is_File_System_Writable())
		return true;

	bool ro = Mount_Read_Only;
	int flags = Mount_Flags;

	Mount_Read_Only = false;
	Mount_Flags &= ~MS_RDONLY;

	bool ret = ReMount(Display_Error);

	Mount_Read_Only = ro;
	Mount_Flags = flags;

	return ret;
}

bool TWPartition::Wipe(string New_File_System) {
	bool wiped = false, update_crypt = false, recreate_media = true;
	int check;

	if (!Can_Be_Wiped) {
		gui_msg(Msg(msg::kError, "cannot_wipe=Partition {1} cannot be wiped.")(Display_Name));
		return false;
	}

	if (Mount_Point == "/cache")
		Log_Offset = 0;

	if (Mount_Point == PartitionManager.Get_Android_Root_Path()) {
		if (tw_get_default_metadata(PartitionManager.Get_Android_Root_Path().c_str()) != 0) {
			gui_msg(Msg(msg::kWarning, "restore_system_context=Unable to get default context for {1} -- Android may not boot.")(PartitionManager.Get_Android_Root_Path()));
		}
	}

	if (Has_Data_Media && Current_File_System == New_File_System) {
		wiped = Wipe_Data_Without_Wiping_Media();
		if (Mount_Point == "/data" && TWFunc::get_log_dir() == DATA_LOGS_DIR) {
			bool created = PartitionManager.Recreate_Logs_Dir();
			if (!created)
				LOGERR("Unable to create log directory for TWRP\n");
		}
		recreate_media = false;
	} else {
		DataManager::GetValue(TW_RM_RF_VAR, check);
		if (check || Use_Rm_Rf)
			wiped = Wipe_RMRF();
		else if (New_File_System == "ext4")
			wiped = Wipe_EXT4();
		else if (New_File_System == "ext2" || New_File_System == "ext3")
			wiped = Wipe_EXTFS(New_File_System);
		else if (New_File_System == "exfat")
			wiped = Wipe_EXFAT();
		else if (New_File_System == "ntfs" || Current_File_System == "tntfs")
			wiped = Wipe_NTFS();
		else if (New_File_System == "yaffs2")
			wiped = Wipe_MTD();
		else if (New_File_System == "f2fs")
			wiped = Wipe_F2FS();
		else if (New_File_System == "vfat")
			wiped = Wipe_FAT();
		else {
			LOGERR("Unable to wipe '%s' -- unknown file system '%s'\n", Mount_Point.c_str(), New_File_System.c_str());
			return false;
		}
		update_crypt = wiped;
		update_crypt = false;
	}

	if (wiped) {
		if (Mount_Point == "/cache" && TWFunc::get_log_dir() != DATA_LOGS_DIR)
			DataManager::Output_Version();

		if (Mount_Point == PartitionManager.Get_Android_Root_Path()) {
			tw_set_default_metadata(PartitionManager.Get_Android_Root_Path().c_str());
		}
		if (update_crypt) {
			Setup_File_System(false);
			if (Is_Encrypted && !Is_Decrypted) {
				// just wiped an encrypted partition back to its unencrypted state
				Is_Encrypted = false;
				Is_Decrypted = false;
				Decrypted_Block_Device = "";
				if (Mount_Point == "/data") {
					DataManager::SetValue(TW_IS_ENCRYPTED, 0);
					DataManager::SetValue(TW_IS_DECRYPTED, 0);
				}
			}
		}

		if (Is_Storage && Mount(false))
			PartitionManager.Add_MTP_Storage(MTP_Storage_ID);
	}

	return wiped;
}

bool TWPartition::Wipe() {
	if (Is_File_System(Current_File_System))
		return Wipe(Current_File_System);
	else
		return Wipe(Fstab_File_System);
}

bool TWPartition::Wipe_AndSec(void) {
	if (!Has_Android_Secure)
		return false;

	if (!Mount(true))
		return false;

	gui_msg(Msg("wiping=Wiping {1}")(Backup_Display_Name));
	TWFunc::removeDir(Mount_Point + "/.android_secure/", true);
	return true;
}

bool TWPartition::Can_Repair() {
	if (Mount_Read_Only)
		return false;
	if (Current_File_System == "vfat" && TWFunc::Path_Exists("/system/bin/fsck.fat"))
		return true;
	else if ((Current_File_System == "ext2" || Current_File_System == "ext3" || Current_File_System == "ext4") && TWFunc::Path_Exists("/system/bin/e2fsck"))
		return true;
	else if (Current_File_System == "exfat" && TWFunc::Path_Exists("/system/bin/fsck.exfat"))
		return true;
	else if (Current_File_System == "f2fs" && TWFunc::Path_Exists("/system/bin/fsck.f2fs"))
		return true;
	else if ((Current_File_System == "ntfs" || Current_File_System == "tntfs") && (TWFunc::Path_Exists("/system/bin/ntfsfix") || TWFunc::Path_Exists("/system/bin/fsck.ntfs")))
		return true;
	return false;
}

bool TWPartition::Repair() {
	string command;

	if (Current_File_System == "vfat") {
		if (!TWFunc::Path_Exists("/system/bin/fsck.fat")) {
			gui_msg(Msg(msg::kError, "repair_not_exist={1} does not exist! Cannot repair!")("fsck.fat"));
			return false;
		}
		if (!UnMount(true))
			return false;
		gui_msg(Msg("repairing_using=Repairing {1} using {2}...")(Display_Name)("fsck.fat"));
		Find_Actual_Block_Device();
		command = "/system/bin/fsck.fat -y " + Actual_Block_Device;
		LOGINFO("Repair command: %s\n", command.c_str());
		if (TWFunc::Exec_Cmd(command) == 0) {
			gui_msg("done=Done.");
			return true;
		} else {
			gui_msg(Msg(msg::kError, "unable_repair=Unable to repair {1}.")(Display_Name));
			return false;
		}
	}
	if (Current_File_System == "ext2" || Current_File_System == "ext3" || Current_File_System == "ext4") {
		if (!TWFunc::Path_Exists("/system/bin/e2fsck")) {
			gui_msg(Msg(msg::kError, "repair_not_exist={1} does not exist! Cannot repair!")("e2fsck"));
			return false;
		}
		if (!UnMount(true))
			return false;
		gui_msg(Msg("repairing_using=Repairing {1} using {2}...")(Display_Name)("e2fsck"));
		Find_Actual_Block_Device();
		command = "/system/bin/e2fsck -fp " + Actual_Block_Device;
		LOGINFO("Repair command: %s\n", command.c_str());
		if (TWFunc::Exec_Cmd(command) == 0) {
			gui_msg("done=Done.");
			return true;
		} else {
			gui_msg(Msg(msg::kError, "unable_repair=Unable to repair {1}.")(Display_Name));
			return false;
		}
	}
	if (Current_File_System == "exfat") {
		if (!TWFunc::Path_Exists("/system/bin/fsck.exfat")) {
			gui_msg(Msg(msg::kError, "repair_not_exist={1} does not exist! Cannot repair!")("fsck.exfat"));
			return false;
		}
		if (!UnMount(true))
			return false;
		gui_msg(Msg("repairing_using=Repairing {1} using {2}...")(Display_Name)("fsck.exfat"));
		Find_Actual_Block_Device();
		command = "/system/bin/fsck.exfat " + Actual_Block_Device;
		LOGINFO("Repair command: %s\n", command.c_str());
		if (TWFunc::Exec_Cmd(command) == 0) {
			gui_msg("done=Done.");
			return true;
		} else {
			gui_msg(Msg(msg::kError, "unable_repair=Unable to repair {1}.")(Display_Name));
			return false;
		}
	}
	if (Current_File_System == "f2fs") {
		if (!TWFunc::Path_Exists("/system/bin/fsck.f2fs")) {
			gui_msg(Msg(msg::kError, "repair_not_exist={1} does not exist! Cannot repair!")("fsck.f2fs"));
			return false;
		}
		if (!UnMount(true))
			return false;
		gui_msg(Msg("repairing_using=Repairing {1} using {2}...")(Display_Name)("fsck.f2fs"));
		Find_Actual_Block_Device();
		command = "/system/bin/fsck.f2fs " + Actual_Block_Device;
		LOGINFO("Repair command: %s\n", command.c_str());
		if (TWFunc::Exec_Cmd(command) == 0) {
			gui_msg("done=Done.");
			return true;
		} else {
			gui_msg(Msg(msg::kError, "unable_repair=Unable to repair {1}.")(Display_Name));
			return false;
		}
	}
	if (Current_File_System == "ntfs" || Current_File_System == "tntfs") {
		string Ntfsfix_Binary;
		if (TWFunc::Path_Exists("/system/bin/ntfsfix"))
			Ntfsfix_Binary = "ntfsfix";
		else if (TWFunc::Path_Exists("/system/bin/fsck.ntfs"))
			Ntfsfix_Binary = "fsck.ntfs";
		else {
			gui_msg(Msg(msg::kError, "repair_not_exist={1} does not exist! Cannot repair!")("ntfsfix"));
			return false;
		}
		if (!UnMount(true))
			return false;
		gui_msg(Msg("repairing_using=Repairing {1} using {2}...")(Display_Name)(Ntfsfix_Binary));
		Find_Actual_Block_Device();
		command = "/system/bin/" + Ntfsfix_Binary + " " + Actual_Block_Device;
		LOGINFO("Repair command: %s\n", command.c_str());
		if (TWFunc::Exec_Cmd(command) == 0) {
			gui_msg("done=Done.");
			return true;
		} else {
			gui_msg(Msg(msg::kError, "unable_repair=Unable to repair {1}.")(Display_Name));
			return false;
		}
	}
	return false;
}

bool TWPartition::Can_Resize() {
	if (Mount_Read_Only)
		return false;
	if ((Current_File_System == "ext2" || Current_File_System == "ext3" || Current_File_System == "ext4") && TWFunc::Path_Exists("/system/bin/resize2fs"))
		return true;
	return false;
}

bool TWPartition::Resize() {
	string command;

	if (Current_File_System == "ext2" || Current_File_System == "ext3" || Current_File_System == "ext4") {
		if (!Can_Repair()) {
			LOGINFO("Cannot resize %s because %s cannot be repaired before resizing.\n", Display_Name.c_str(), Display_Name.c_str());
			gui_msg(Msg(msg::kError, "cannot_resize=Cannot resize {1}.")(Display_Name));
			return false;
		}
		if (!TWFunc::Path_Exists("/system/bin/resize2fs")) {
			LOGINFO("resize2fs does not exist! Cannot resize!\n");
			gui_msg(Msg(msg::kError, "cannot_resize=Cannot resize {1}.")(Display_Name));
			return false;
		}
		// Repair will unmount so no need to do it twice
		gui_msg(Msg("repair_resize=Repairing {1} before resizing.")( Display_Name));
		if (!Repair())
			return false;
		gui_msg(Msg("resizing=Resizing {1} using {2}...")(Display_Name)("resize2fs"));
		Find_Actual_Block_Device();
		command = "/system/bin/resize2fs " + Actual_Block_Device;
		if (Length != 0) {
			unsigned long long Actual_Size = IOCTL_Get_Block_Size();
			if (Actual_Size == 0)
				return false;

			unsigned long long Block_Count;
			if (Length < 0) {
				// Reduce overall size by this length
				Block_Count = (Actual_Size / 1024LLU) - ((unsigned long long)(Length * -1) / 1024LLU);
			} else {
				// This is the size, not a size reduction
				Block_Count = ((unsigned long long)(Length) / 1024LLU);
			}
			char temp[256];
			sprintf(temp, "%llu", Block_Count);
			command += " ";
			command += temp;
			command += "K";
		}
		LOGINFO("Resize command: %s\n", command.c_str());
		if (TWFunc::Exec_Cmd(command) == 0) {
			Update_Size(true);
			gui_msg("done=Done.");
			return true;
		} else {
			Update_Size(true);
			gui_msg(Msg(msg::kError, "unable_resize=Unable to resize {1}.")(Display_Name));
			return false;
		}
	}
	return false;
}

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;
}

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/%s\n", part_settings->Backup_Folder.c_str(), Backup_FileName.c_str());

	string Restore_File_System = Get_Restore_File_System(part_settings);

	if (Is_File_System(Restore_File_System))
		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(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(".");
	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);
	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 == BM_NONE)
		return "none";
	else if (Backup_Method == BM_FILES)
		return "files";
	else if (Backup_Method == BM_DD)
		return "dd";
	else if (Backup_Method == BM_FLASH_UTILS)
		return "flash_utils";
	else
		return "undefined";
	return "ERROR!";
}

bool TWPartition::Decrypt(string Password) {
	LOGINFO("STUB TWPartition::Decrypt, password: '%s'\n", Password.c_str());
	// Is this needed?
	return 1;
}

bool TWPartition::Wipe_Encryption() {
	bool Save_Data_Media = Has_Data_Media;
	bool ret = false;
	BasePartition* base_partition = make_partition();

	if (!base_partition->PreWipeEncryption())
		goto exit;

	Find_Actual_Block_Device();
	if (!Is_Present) {
		LOGINFO("Block device not present, cannot format %s.\n", Display_Name.c_str());
		gui_msg(Msg(msg::kError, "unable_to_wipe=Unable to wipe {1}.")(Display_Name));
		return false;
	}

#ifdef TW_INCLUDE_CRYPTO
	if (!UnMount(true))
		return false;
	if (Is_Decrypted && !Decrypted_Block_Device.empty()) {
		if (delete_crypto_blk_dev((char*)("userdata")) != 0) {
			LOGERR("Error deleting crypto block device, continuing anyway.\n");
		}
	}
#endif
	Has_Data_Media = false;
	Decrypted_Block_Device = "";
	Is_Decrypted = false;
	Is_Encrypted = false;
	if (Wipe(Fstab_File_System)) {
		Has_Data_Media = Save_Data_Media;
		if (Has_Data_Media && !Symlink_Mount_Point.empty()) {
			if (Mount(false))
				PartitionManager.Add_MTP_Storage(MTP_Storage_ID);
		}
		DataManager::SetValue(TW_IS_ENCRYPTED, 0);
#ifndef TW_OEM_BUILD
		gui_msg("format_data_msg=You may need to reboot recovery to be able to use /data again.");
#endif
		if (Is_FBE) {
			gui_msg(Msg(msg::kWarning, "data_media_fbe_msg=TWRP will not recreate /data/media on an FBE device. Please reboot into your rom to create /data/media."));
		}

		ret = true;
		if (!Key_Directory.empty())
			ret = PartitionManager.Wipe_By_Path(Key_Directory);
		if (ret)
			ret = base_partition->PostWipeEncryption();
		goto exit;
	} else {
		Has_Data_Media = Save_Data_Media;
		gui_err("format_data_err=Unable to format to remove encryption.");
		if (Has_Data_Media && Mount(false))
			PartitionManager.Add_MTP_Storage(MTP_Storage_ID);
		goto exit;
	}
exit:
	delete base_partition;
	return ret;
}

void TWPartition::Check_FS_Type() {
	const char* type;
	blkid_probe pr;

	if (Fstab_File_System == "yaffs2" || Fstab_File_System == "mtd" || Fstab_File_System == "bml" || Ignore_Blkid)
		return; // Running blkid on some mtd devices causes a massive crash or needs to be skipped

	Find_Actual_Block_Device();
	if (!Is_Present)
		return;

	pr = blkid_new_probe_from_filename(Actual_Block_Device.c_str());
	if (blkid_do_fullprobe(pr)) {
		blkid_free_probe(pr);
		LOGINFO("Can't probe device %s\n", Actual_Block_Device.c_str());
		return;
	}

	if (blkid_probe_lookup_value(pr, "TYPE", &type, NULL) < 0) {
		blkid_free_probe(pr);
		LOGINFO("can't find filesystem on device %s\n", Actual_Block_Device.c_str());
		return;
	}

	Current_File_System = type;
	blkid_free_probe(pr);
	if (fs_flags.size() > 1) {
		std::vector<partition_fs_flags_struct>::iterator iter;
		std::vector<partition_fs_flags_struct>::iterator found = fs_flags.begin();

		for (iter = fs_flags.begin(); iter != fs_flags.end(); iter++) {
			if (iter->File_System == Current_File_System) {
				found = iter;
				break;
			}
		}
		// If we don't find a match, we default the flags to the first set of flags that we received from the fstab
		if (Mount_Flags != found->Mount_Flags || Mount_Options != found->Mount_Options) {
			Mount_Flags = found->Mount_Flags;
			Mount_Options = found->Mount_Options;
			LOGINFO("Mount_Flags: %i, Mount_Options: %s\n", Mount_Flags, Mount_Options.c_str());
		}
	}
}

bool TWPartition::Wipe_EXTFS(string File_System) {
	if (!UnMount(true))
		return false;

#if PLATFORM_SDK_VERSION < 28
	if (!TWFunc::Path_Exists("/system/bin/mke2fs"))
#else
	if (!TWFunc::Path_Exists("/system/bin/mke2fs") || !TWFunc::Path_Exists("/system/bin/e2fsdroid"))
#endif
		return Wipe_RMRF();

	int ret;
	bool NeedPreserveFooter = true;

	Find_Actual_Block_Device();
	if (!Is_Present) {
		LOGINFO("Block device not present, cannot wipe %s.\n", Display_Name.c_str());
		gui_msg(Msg(msg::kError, "unable_to_wipe=Unable to wipe {1}.")(Display_Name));
		return false;
	}

	/**
	 * On decrypted devices, IOCTL_Get_Block_Size calculates size on device mapper,
	 * so there's no need to preserve footer.
	 */
	if ((Is_Decrypted && !Decrypted_Block_Device.empty()) ||
			Crypto_Key_Location != "footer") {
		NeedPreserveFooter = false;
	}

	unsigned long long dev_sz = TWFunc::IOCTL_Get_Block_Size(Actual_Block_Device.c_str());
	if (!dev_sz)
		return false;

	if (NeedPreserveFooter)
		Length < 0 ? dev_sz += Length : dev_sz -= CRYPT_FOOTER_OFFSET;

	char dout[16];
	sprintf(dout, "%llu", dev_sz / 4096);

	//string size_str =to_string(dev_sz / 4096);
	string size_str = dout;
	string Command;

	gui_msg(Msg("formatting_using=Formatting {1} using {2}...")(Display_Name)("mke2fs"));

	// Execute mke2fs to create empty ext4 filesystem
	Command = "mke2fs -t " + File_System + " -b 4096 " + Actual_Block_Device + " " + size_str;
	LOGINFO("mke2fs command: %s\n", Command.c_str());
	ret = TWFunc::Exec_Cmd(Command);
	if (ret) {
		gui_msg(Msg(msg::kError, "unable_to_wipe=Unable to wipe {1}.")(Display_Name));
		return false;
	}

	if (TWFunc::Path_Exists("/system/bin/e2fsdroid")) {
		const string& File_Contexts_Entry = (Mount_Point == "/system_root" ? "/" : Mount_Point);
		char *secontext = NULL;
		if (!selinux_handle || selabel_lookup(selinux_handle, &secontext, File_Contexts_Entry.c_str(), S_IFDIR) < 0) {
			LOGINFO("Cannot lookup security context for '%s'\n", Mount_Point.c_str());
		} else {
			// Execute e2fsdroid to initialize selinux context
			if (Mount_Point == "/persist") {
				Mount(true);
				TWFunc::removeDir("/persist/lost+found", false);
				UnMount(true);
			}
			Command = "e2fsdroid -e -S /file_contexts -a " + File_Contexts_Entry + " " + Actual_Block_Device;
			LOGINFO("e2fsdroid command: %s\n", Command.c_str());
			ret = TWFunc::Exec_Cmd(Command);
			if (ret) {
				gui_msg(Msg(msg::kError, "unable_to_wipe=Unable to wipe {1}.")(Display_Name));
				return false;
			}
		}
	} else {
		LOGINFO("e2fsdroid not present\n");
	}

	if (NeedPreserveFooter)
		Wipe_Crypto_Key();
	Current_File_System = File_System;
	Recreate_AndSec_Folder();
	gui_msg("done=Done.");
	return true;
}

bool TWPartition::Wipe_EXT4() {
#ifdef USE_EXT4
	int ret;
	bool NeedPreserveFooter = true;

	if (!UnMount(true))
		return false;

	Find_Actual_Block_Device();
	if (!Is_Present) {
		LOGINFO("Block device not present, cannot wipe %s.\n", Display_Name.c_str());
		gui_msg(Msg(msg::kError, "unable_to_wipe=Unable to wipe {1}.")(Display_Name));
		return false;
	}

	/**
	 * On decrypted devices, IOCTL_Get_Block_Size calculates size on device mapper,
	 * so there's no need to preserve footer.
	 */
	if ((Is_Decrypted && !Decrypted_Block_Device.empty()) ||
			Crypto_Key_Location != "footer") {
		NeedPreserveFooter = false;
	}

	unsigned long long dev_sz = TWFunc::IOCTL_Get_Block_Size(Actual_Block_Device.c_str());
	if (!dev_sz)
		return false;

	if (NeedPreserveFooter)
		Length < 0 ? dev_sz += Length : dev_sz -= CRYPT_FOOTER_OFFSET;

	char *secontext = NULL;

	gui_msg(Msg("formatting_using=Formatting {1} using {2}...")(Display_Name)("make_ext4fs"));

	if (!selinux_handle || selabel_lookup(selinux_handle, &secontext, Mount_Point.c_str(), S_IFDIR) < 0) {
		LOGINFO("Cannot lookup security context for '%s'\n", Mount_Point.c_str());
		ret = make_ext4fs(Actual_Block_Device.c_str(), dev_sz, Mount_Point.c_str(), NULL);
	} else {
		ret = make_ext4fs(Actual_Block_Device.c_str(), dev_sz, Mount_Point.c_str(), selinux_handle);
	}
	if (ret != 0) {
		gui_msg(Msg(msg::kError, "unable_to_wipe=Unable to wipe {1}.")(Display_Name));
		return false;
	} else {
		if (NeedPreserveFooter)
			Wipe_Crypto_Key();
		string sedir = Mount_Point + "/lost+found";
		PartitionManager.Mount_By_Path(sedir.c_str(), true);
		rmdir(sedir.c_str());
		mkdir(sedir.c_str(), S_IRWXU | S_IRWXG | S_IWGRP | S_IXGRP);
		return true;
	}
#else
	return Wipe_EXTFS("ext4");
#endif
}

bool TWPartition::Wipe_FAT() {
	string command;

	if (!UnMount(true))
		return false;

	if (TWFunc::Path_Exists("/system/bin/mkfs.fat")) {
		gui_msg(Msg("formatting_using=Formatting {1} using {2}...")(Display_Name)("mkfs.fat"));
		Find_Actual_Block_Device();
		command = "mkfs.fat " + Actual_Block_Device;
		if (TWFunc::Exec_Cmd(command) == 0) {
			Current_File_System = "vfat";
			Recreate_AndSec_Folder();
			gui_msg("done=Done.");
			return true;
		} else {
			gui_msg(Msg(msg::kError, "unable_to_wipe=Unable to wipe {1}.")(Display_Name));
			return false;
		}
		return true;
	}
	else
		return Wipe_RMRF();

	return false;
}

bool TWPartition::Wipe_EXFAT() {
	string command;

	if (!UnMount(true))
		return false;
	if (TWFunc::Path_Exists("/system/bin/mkexfatfs")) {
		gui_msg(Msg("formatting_using=Formatting {1} using {2}...")(Display_Name)("mkexfatfs"));
		Find_Actual_Block_Device();
		command = "mkexfatfs " + Actual_Block_Device;
		if (TWFunc::Exec_Cmd(command) == 0) {
			Recreate_AndSec_Folder();
			gui_msg("done=Done.");
			return true;
		} else {
			gui_msg(Msg(msg::kError, "unable_to_wipe=Unable to wipe {1}.")(Display_Name));
			return false;
		}
		return true;
	}
	return false;
}

bool TWPartition::Wipe_MTD() {
	if (!UnMount(true))
		return false;

	gui_msg(Msg("formatting_using=Formatting {1} using {2}...")(Display_Name)("MTD"));

	mtd_scan_partitions();
	const MtdPartition* mtd = mtd_find_partition_by_name(MTD_Name.c_str());
	if (mtd == NULL) {
		LOGERR("No mtd partition named '%s'", MTD_Name.c_str());
		return false;
	}

	MtdWriteContext* ctx = mtd_write_partition(mtd);
	if (ctx == NULL) {
		LOGERR("Can't write '%s', failed to format.", MTD_Name.c_str());
		return false;
	}
	if (mtd_erase_blocks(ctx, -1) == -1) {
		mtd_write_close(ctx);
		LOGERR("Failed to format '%s'", MTD_Name.c_str());
		return false;
	}
	if (mtd_write_close(ctx) != 0) {
		LOGERR("Failed to close '%s'", MTD_Name.c_str());
		return false;
	}
	Current_File_System = "yaffs2";
	Recreate_AndSec_Folder();
	gui_msg("done=Done.");
	return true;
}

bool TWPartition::Wipe_RMRF() {
	if (!Mount(true))
		return false;
	// This is the only wipe that leaves the partition mounted, so we
	// must manually remove the partition from MTP if it is a storage
	// partition.
	if (Is_Storage)
		PartitionManager.Remove_MTP_Storage(MTP_Storage_ID);

	gui_msg(Msg("remove_all=Removing all files under '{1}'")(Mount_Point));
	TWFunc::removeDir(Mount_Point, true);
	Recreate_AndSec_Folder();
	return true;
}

bool TWPartition::Wipe_F2FS() {
	std::string command;
	std::string f2fs_bin;

	if (!UnMount(true))
		return false;

	if (TWFunc::Path_Exists("/system/bin/mkfs.f2fs"))
		f2fs_bin = "/system/bin/mkfs.f2fs";
	else if (TWFunc::Path_Exists("/system/bin/make_f2fs"))
		f2fs_bin = "/system/bin/make_f2fs";
	else {
		LOGINFO("mkfs.f2fs binary not found, using rm -rf to wipe.\n");
		return Wipe_RMRF();
	}

	bool NeedPreserveFooter = true;

	Find_Actual_Block_Device();
	if (!Is_Present) {
		LOGINFO("Block device not present, cannot wipe %s.\n", Display_Name.c_str());
		gui_msg(Msg(msg::kError, "unable_to_wipe=Unable to wipe {1}.")(Display_Name));
		return false;
	}
	
	unsigned long long dev_sz = TWFunc::IOCTL_Get_Block_Size(Actual_Block_Device.c_str());
	if (!dev_sz)
		return false;

	if (NeedPreserveFooter)
		Length < 0 ? dev_sz += Length : dev_sz -= CRYPT_FOOTER_OFFSET;

	char dev_sz_str[48];
	sprintf(dev_sz_str, "%llu", (dev_sz / 4096));
	command = f2fs_bin + " -d1 -f -O encrypt -O quota -O verity -w 4096 " + Actual_Block_Device + " " + dev_sz_str;
	if (TWFunc::Path_Exists("/system/bin/sload.f2fs")) {
		command += " && sload.f2fs -t /data " + Actual_Block_Device;
	}

	/**
	 * On decrypted devices, IOCTL_Get_Block_Size calculates size on device mapper,
	 * so there's no need to preserve footer.
	 */
	if ((Is_Decrypted && !Decrypted_Block_Device.empty()) ||
			Crypto_Key_Location != "footer") {
		NeedPreserveFooter = false;
	}
	LOGINFO("mkfs.f2fs command: %s\n", f2fs_bin.c_str());
	if (TWFunc::Exec_Cmd(command) == 0) {
		if (NeedPreserveFooter)
			Wipe_Crypto_Key();
		Recreate_AndSec_Folder();
		gui_msg("done=Done.");
		return true;
	} else {
		gui_msg(Msg(msg::kError, "unable_to_wipe=Unable to wipe {1}.")(Display_Name));
		return false;
	}
	return true;
}

bool TWPartition::Wipe_NTFS() {
	string command;
	string Ntfsmake_Binary;

	if (!UnMount(true))
		return false;

	if (TWFunc::Path_Exists("/system/bin/mkntfs"))
		Ntfsmake_Binary = "mkntfs";
	else if (TWFunc::Path_Exists("/system/bin/mkfs.ntfs"))
		Ntfsmake_Binary = "mkfs.ntfs";
	else
		return false;

	gui_msg(Msg("formatting_using=Formatting {1} using {2}...")(Display_Name)(Ntfsmake_Binary));
	Find_Actual_Block_Device();
	command = "/system/bin/" + Ntfsmake_Binary + " " + Actual_Block_Device;
	if (TWFunc::Exec_Cmd(command) == 0) {
		Recreate_AndSec_Folder();
		gui_msg("done=Done.");
		return true;
	} else {
		gui_msg(Msg(msg::kError, "unable_to_wipe=Unable to wipe {1}.")(Display_Name));
		return false;
	}
	return false;
}

bool TWPartition::Wipe_Data_Without_Wiping_Media() {
#ifdef TW_OEM_BUILD
	// In an OEM Build we want to do a full format
	return Wipe_Encryption();
#else
	bool ret = false;

	if (!Mount(true))
		return false;

	gui_msg("wiping_data=Wiping data without wiping /data/media ...");
	ret = Wipe_Data_Without_Wiping_Media_Func(Mount_Point + "/");
	if (ret)
		gui_msg("done=Done.");
	return ret;
#endif // ifdef TW_OEM_BUILD
}

bool TWPartition::Wipe_Data_Without_Wiping_Media_Func(const string& parent __unused) {
	string dir;

	DIR* d;
	d = opendir(parent.c_str());
	if (d != NULL) {
		struct dirent* de;
		while ((de = readdir(d)) != NULL) {
			if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0)	 continue;

			dir = parent;
			dir.append(de->d_name);
			if (wipe_exclusions.check_skip_dirs(dir)) {
				LOGINFO("skipped '%s'\n", dir.c_str());
				continue;
			}
			if (de->d_type == DT_DIR) {
				dir.append("/");
				if (!Wipe_Data_Without_Wiping_Media_Func(dir)) {
					closedir(d);
					return false;
				}
				rmdir(dir.c_str());
			} else if (de->d_type == DT_REG || de->d_type == DT_LNK || de->d_type == DT_FIFO || de->d_type == DT_SOCK) {
				if (unlink(dir.c_str()) != 0)
					LOGINFO("Unable to unlink '%s': %s\n", dir.c_str(), strerror(errno));
			}
		}
		closedir(d);

		return true;
	}
	gui_msg(Msg(msg::kError, "error_opening_strerr=Error opening: '{1}' ({2})")(Mount_Point)(strerror(errno)));
	return false;
}

void TWPartition::Wipe_Crypto_Key() {
	Find_Actual_Block_Device();
	if (Crypto_Key_Location.empty())
		return;
	else if (Crypto_Key_Location == "footer") {
		int fd = open(Actual_Block_Device.c_str(), O_RDWR);
		if (fd < 0) {
			gui_print_color("warning", "Unable to open '%s' to wipe crypto key\n", Actual_Block_Device.c_str());
			return;
		}

		unsigned int block_count;
		if ((ioctl(fd, BLKGETSIZE, &block_count)) == -1) {
			gui_print_color("warning", "Unable to get block size for wiping crypto footer.\n");
		} else {
			int newlen = Length < 0 ? -Length : CRYPT_FOOTER_OFFSET;
			off64_t offset = ((off64_t)block_count * 512) - newlen;
			if (lseek64(fd, offset, SEEK_SET) == -1) {
				gui_print_color("warning", "Unable to lseek64 for wiping crypto footer.\n");
			} else {
				void* buffer = malloc(newlen);
				if (!buffer) {
					gui_print_color("warning", "Failed to malloc for wiping crypto footer.\n");
				} else {
					memset(buffer, 0, newlen);
					int ret = write(fd, buffer, newlen);
					if (ret != newlen) {
						gui_print_color("warning", "Failed to wipe crypto footer.\n");
					} else {
						LOGINFO("Successfully wiped crypto footer.\n");
					}
					free(buffer);
				}
			}
		}
		close(fd);
	} else {
		if (TWFunc::IOCTL_Get_Block_Size(Crypto_Key_Location.c_str()) >= 16384LLU) {
			string Command = "dd of='" + Crypto_Key_Location + "' if=/dev/zero bs=16384 count=1";
			TWFunc::Exec_Cmd(Command);
		} else {
			LOGINFO("Crypto key location reports size < 16K so not wiping crypto footer.\n");
		}
	}
}

bool TWPartition::Backup_Tar(PartitionSettings *part_settings, pid_t *tar_fork_pid) {
	string Full_FileName;
	twrpTar tar;

	if (!Mount(true))
		return false;

	TWFunc::GUI_Operation_Text(TW_BACKUP_TEXT, Backup_Display_Name, gui_parse_text("{@backing}"));
	gui_msg(Msg("backing_up=Backing up {1}...")(Backup_Display_Name));

	DataManager::GetValue(TW_USE_COMPRESSION_VAR, tar.use_compression);

#ifndef TW_EXCLUDE_ENCRYPTED_BACKUPS
	if (Can_Encrypt_Backup) {
		DataManager::GetValue("tw_encrypt_backup", tar.use_encryption);
		if (tar.use_encryption) {
			if (Use_Userdata_Encryption)
				tar.userdata_encryption = tar.use_encryption;
			string Password;
			DataManager::GetValue("tw_backup_password", Password);
			tar.setpassword(Password);
		} else {
			tar.use_encryption = 0;
		}
	}
#endif

	Backup_FileName = Backup_Name + "." + Current_File_System + ".win";
	Full_FileName = part_settings->Backup_Folder + "/" + Backup_FileName;
	if (Has_Data_Media)
		gui_msg(Msg(msg::kWarning, "backup_storage_warning=Backups of {1} do not include any files in internal storage such as pictures or downloads.")(Display_Name));
	if (Mount_Point == "/data" && DataManager::GetIntValue(TW_IS_FBE)) {
		std::vector<users_struct>::iterator iter;
		std::vector<users_struct>* userList = PartitionManager.Get_Users_List();
		for (iter = userList->begin(); iter != userList->end(); iter++) {
			if (!(*iter).isDecrypted && (*iter).userId != "0") {
				gui_msg(Msg(msg::kWarning,
				"backup_storage_undecrypt_warning=Backup will not include some files from user {1} "
				"because the user is not decrypted.")((*iter).userId));
				backup_exclusions.add_absolute_dir("/data/system_ce/" + (*iter).userId);
				backup_exclusions.add_absolute_dir("/data/misc_ce/" + (*iter).userId);
				backup_exclusions.add_absolute_dir("/data/vendor_ce/" + (*iter).userId);
				backup_exclusions.add_absolute_dir("/data/media/" + (*iter).userId);
				backup_exclusions.add_absolute_dir("/data/user/" + (*iter).userId);
			}
		}
	}
	tar.part_settings = part_settings;
	tar.backup_exclusions = &backup_exclusions;
	tar.setdir(Backup_Path);
	tar.setfn(Full_FileName);
	tar.setsize(Backup_Size);
	tar.partition_name = Backup_Name;
	tar.backup_folder = part_settings->Backup_Folder;
	if (tar.createTarFork(tar_fork_pid) != 0)
		return false;
	return true;
}

bool TWPartition::Backup_Image(PartitionSettings *part_settings) {
	string Full_FileName, adb_file_name;

	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";

	if (part_settings->adbbackup) {
		Full_FileName = TW_ADB_BACKUP;
		adb_file_name  = part_settings->Backup_Folder + "/" + Backup_FileName;
	}
	else
		Full_FileName = part_settings->Backup_Folder + "/" + Backup_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(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;

	if (part_settings->PM_Method == PM_BACKUP) {
		srcfn = Actual_Block_Device;
		if (part_settings->adbbackup)
			destfn = TW_ADB_BACKUP;
		else {
			destfn = part_settings->Backup_Folder + "/" + Backup_FileName;
		}
	}
	else {
		destfn = Actual_Block_Device;
		if (part_settings->adbbackup) {
			srcfn = TW_ADB_RESTORE;
		} else {
			srcfn = part_settings->Backup_Folder + "/" + Backup_FileName;
			Remain = TWFunc::Get_File_Size(srcfn);
		}
	}

	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})")(srcfn.c_str())(strerror(errno)));
		return false;
	}

	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})")(destfn.c_str())(strerror(errno)));
		goto exit;
	}

	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;
	}

	if (part_settings->progress)
		part_settings->progress->SetPartitionSize(part_settings->total_restore_size);

	while (Remain > 0) {
		if (Remain < RW_Block_Size)
			bs = (ssize_t)(Remain);
		if (read(src_fd, buffer, bs) != bs) {
			LOGINFO("Error reading source fd (%s)\n", strerror(errno));
			goto exit;
		}
		if (write(dest_fd, buffer, bs) != bs) {
			LOGINFO("Error writing destination fd (%s)\n", strerror(errno));
			goto exit;
		}
		backedup_size += (unsigned long long)(bs);
		Remain -= (unsigned long long)(bs);
		if (part_settings->progress)
			part_settings->progress->UpdateSize(backedup_size);
		if (PartitionManager.Check_Backup_Cancel() != 0)
			goto exit;
	}
	if (part_settings->progress)
		part_settings->progress->UpdateDisplayDetails(true);
	fsync(dest_fd);

	if (!part_settings->adbbackup && part_settings->PM_Method == PM_BACKUP) {
		tw_set_default_metadata(destfn.c_str());
		LOGINFO("Restored default metadata for %s\n", destfn.c_str());
	}

	ret = true;
exit:
	if (src_fd >= 0)
		close(src_fd);
	if (dest_fd >= 0)
		close(dest_fd);
	if (buffer)
		free(buffer);
	return ret;
}

bool TWPartition::Backup_Dump_Image(PartitionSettings *part_settings) {
	string Full_FileName, Command;

	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 (part_settings->progress)
		part_settings->progress->SetPartitionSize(Backup_Size);

	Backup_FileName = Backup_Name + "." + Current_File_System + ".win";
	Full_FileName = part_settings->Backup_Folder + "/" + 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());
	if (TWFunc::Get_File_Size(Full_FileName) == 0) {
		// Actual size may not match backup size due to bad blocks on MTD devices so just check for 0 bytes
		gui_msg(Msg(msg::kError, "backup_size=Backup file size for '{1}' is 0 bytes.")(Full_FileName));
		return false;
	}
	if (part_settings->progress)
		part_settings->progress->UpdateSize(Backup_Size);

	return true;
}

unsigned long long TWPartition::Get_Restore_Size(PartitionSettings *part_settings) {
	if (!part_settings->adbbackup) {
		InfoManager restore_info(part_settings->Backup_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;
			}
		}
	}

	string Full_FileName = part_settings->Backup_Folder + "/" + Backup_FileName;
	string Restore_File_System = Get_Restore_File_System(part_settings);

	if (Is_Image(Restore_File_System)) {
		Restore_Size = TWFunc::Get_File_Size(Full_FileName);
		return Restore_Size;
	}

	twrpTar tar;
	tar.setdir(Backup_Path);
	tar.setfn(Full_FileName);
	tar.backup_name = Full_FileName;
#ifndef TW_EXCLUDE_ENCRYPTED_BACKUPS
	string Password;
	DataManager::GetValue("tw_restore_password", Password);
	if (!Password.empty())
		tar.setpassword(Password);
#endif
	tar.partition_name = Backup_Name;
	tar.backup_folder = part_settings->Backup_Folder;
	tar.part_settings = part_settings;
	Restore_Size = tar.get_size();
	return Restore_Size;
}

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())
			return false;
	} else {
		gui_msg(Msg("wiping=Wiping {1}")(Backup_Display_Name));
		if (Has_Data_Media && Mount_Point == "/data" && Restore_File_System != Current_File_System) {
			gui_msg(Msg(msg::kWarning, "datamedia_fs_restore=WARNING: This /data backup was made with {1} file system! The backup may not boot unless you change back to {1}.")(Restore_File_System));
			if (!Wipe_Data_Without_Wiping_Media())
				return false;
		} else {
			if (!Wipe(Restore_File_System))
				return false;
		}
	}
	TWFunc::GUI_Operation_Text(TW_RESTORE_TEXT, Backup_Display_Name, gui_parse_text("{@restoring_hdr}"));
	gui_msg(Msg("restoring=Restoring {1}...")(Backup_Display_Name));

	// Remount as read/write as needed so we can restore the backup
	if (!ReMount_RW(true))
		return false;

	Full_FileName = part_settings->Backup_Folder + "/" + Backup_FileName;
	twrpTar tar;
	tar.part_settings = part_settings;
	tar.setdir(Backup_Path);
	tar.setfn(Full_FileName);
	tar.backup_name = Backup_Name;
#ifndef TW_EXCLUDE_ENCRYPTED_BACKUPS
	string Password;
	DataManager::GetValue("tw_restore_password", Password);
	if (!Password.empty())
		tar.setpassword(Password);
#endif
	part_settings->progress->SetPartitionSize(Get_Restore_Size(part_settings));
	if (tar.extractTarFork() != 0)
		ret = false;
	else
		ret = true;
#ifdef HAVE_CAPABILITIES
	// Restore capabilities to the run-as binary
	if (Mount_Point == PartitionManager.Get_Android_Root_Path() && Mount(true) && TWFunc::Path_Exists("/system/bin/run-as")) {
		struct vfs_cap_data cap_data;
		uint64_t capabilities = (1 << CAP_SETUID) | (1 << CAP_SETGID);

		memset(&cap_data, 0, sizeof(cap_data));
		cap_data.magic_etc = VFS_CAP_REVISION | VFS_CAP_FLAGS_EFFECTIVE;
		cap_data.data[0].permitted = (uint32_t) (capabilities & 0xffffffff);
		cap_data.data[0].inheritable = 0;
		cap_data.data[1].permitted = (uint32_t) (capabilities >> 32);
		cap_data.data[1].inheritable = 0;
		if (setxattr("/system/bin/run-as", XATTR_NAME_CAPS, &cap_data, sizeof(cap_data), 0) < 0) {
			LOGINFO("Failed to reset capabilities of /system/bin/run-as binary.\n");
		} else {
			LOGINFO("Reset capabilities of /system/bin/run-as binary successful.\n");
		}
	}
#endif
	if (Mount_Read_Only || Mount_Flags & MS_RDONLY)
		// Remount as read only when restoration is complete
		ReMount(true);

	return ret;
}

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));

	if (part_settings->adbbackup)
		Full_FileName = TW_ADB_RESTORE;
	else
		Full_FileName = part_settings->Backup_Folder + "/" + Backup_FileName;

	if (Restore_File_System == "emmc") {
		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, part_settings->progress))
			return false;
	}

	if (part_settings->adbbackup) {
		if (!twadbbu::Write_TWEOF())
			return false;
	}
	return true;
}

bool TWPartition::Update_Size(bool Display_Error) {
	bool ret = false, Was_Already_Mounted = false;

	Find_Actual_Block_Device();

	if (Actual_Block_Device.empty())
		return false;

	if (!Can_Be_Mounted && !Is_Encrypted) {
		if (TWFunc::Path_Exists(Actual_Block_Device) && Find_Partition_Size()) {
			Used = Size;
			Backup_Size = Size;
			return true;
		}
		return false;
	}

	Was_Already_Mounted = Is_Mounted();

	if (Removable || Is_Encrypted) {
		if (!Mount(false))
			return true;
	} else if (!Mount(Display_Error))
		return false;

	ret = Get_Size_Via_statfs(Display_Error);
	if (!ret || Size == 0) {
		if (!Get_Size_Via_df(Display_Error)) {
			if (!Was_Already_Mounted)
				UnMount(false);
			return false;
		}
	}

	if (Has_Data_Media) {
		if (Mount(Display_Error)) {
			Used = backup_exclusions.Get_Folder_Size(Mount_Point);
			Backup_Size = Used;
			int bak = (int)(Used / 1048576LLU);
			int fre = (int)(Free / 1048576LLU);
			LOGINFO("Data backup size is %iMB, free: %iMB.\n", bak, fre);
		} else {
			if (!Was_Already_Mounted)
				UnMount(false);
			return false;
		}
	} else if (Has_Android_Secure) {
		if (Mount(Display_Error))
			Backup_Size = backup_exclusions.Get_Folder_Size(Backup_Path);
		else {
			if (!Was_Already_Mounted)
				UnMount(false);
			return false;
		}
	}
	if (!Was_Already_Mounted)
		UnMount(false);
	return true;
}

bool TWPartition::Find_Wildcard_Block_Devices(const string& Device) {
	int mount_point_index = 0; // we will need to create separate mount points for each partition found and we use this index to name each one
	string Path = TWFunc::Get_Path(Device);
	string Dev = TWFunc::Get_Filename(Device);
	size_t wildcard_index = Dev.find("*");
	if (wildcard_index != string::npos)
		Dev = Dev.substr(0, wildcard_index);
	wildcard_index = Dev.size();
	DIR* d = opendir(Path.c_str());
	if (d == NULL) {
		LOGINFO("Error opening '%s': %s\n", Path.c_str(), strerror(errno));
		return false;
	}
	struct dirent* de;
	while ((de = readdir(d)) != NULL) {
		if (de->d_type != DT_BLK || strlen(de->d_name) <= wildcard_index || strncmp(de->d_name, Dev.c_str(), wildcard_index) != 0)
			continue;

		string item = Path + "/";
		item.append(de->d_name);
		if (PartitionManager.Find_Partition_By_Block_Device(item))
			continue;
		TWPartition *part = new TWPartition;
		char buffer[MAX_FSTAB_LINE_LENGTH];
		sprintf(buffer, "%s %s-%i auto defaults defaults", item.c_str(), Mount_Point.c_str(), ++mount_point_index);
		part->Process_Fstab_Line(buffer, false, NULL);
		char display[MAX_FSTAB_LINE_LENGTH];
		sprintf(display, "%s %i", Storage_Name.c_str(), mount_point_index);
		part->Storage_Name = display;
		part->Display_Name = display;
		part->Primary_Block_Device = item;
		part->Wildcard_Block_Device = false;
		part->Is_SubPartition = true;
		part->SubPartition_Of = Mount_Point;
		part->Is_Storage = Is_Storage;
		part->Can_Be_Mounted = true;
		part->Removable = true;
		part->Can_Be_Wiped = Can_Be_Wiped;
		part->Wipe_Available_in_GUI = Wipe_Available_in_GUI;
		part->Find_Actual_Block_Device();
		part->Update_Size(false);
		Has_SubPartition = true;
		PartitionManager.Output_Partition(part);
		PartitionManager.Add_Partition(part);
	}
	closedir(d);
	return (mount_point_index > 0);
}

void TWPartition::Find_Actual_Block_Device(void) {
	if (!Sysfs_Entry.empty() && Primary_Block_Device.empty() && Decrypted_Block_Device.empty()) {
		/* Sysfs_Entry.empty() indicates if this is a sysfs entry that begins with /device/
		 * If we have a syfs entry then we are looking for this device from a uevent add.
		 * The uevent add will set the primary block device based on the data we receive from
		 * after checking for adopted storage. If the device ends up being adopted, then the
		 * decrypted block device will be set instead of the primary block device. */
		Is_Present = false;
		return;
	}
	if (Wildcard_Block_Device && !Is_Adopted_Storage) {
		Is_Present = false;
		Actual_Block_Device = "";
		Can_Be_Mounted = false;
		if (!Find_Wildcard_Block_Devices(Primary_Block_Device)) {
			string Dev = Primary_Block_Device.substr(0, Primary_Block_Device.find("*"));
			if (TWFunc::Path_Exists(Dev)) {
				Is_Present = true;
				Can_Be_Mounted = true;
				Actual_Block_Device = Dev;
			}
		}
		return;
	} else if (Is_Decrypted && !Decrypted_Block_Device.empty()) {
		Actual_Block_Device = Decrypted_Block_Device;
		if (TWFunc::Path_Exists(Decrypted_Block_Device)) {
			Is_Present = true;
			return;
		}
	} else if (SlotSelect && TWFunc::Path_Exists(Primary_Block_Device + PartitionManager.Get_Active_Slot_Suffix())) {
		Actual_Block_Device = Primary_Block_Device + PartitionManager.Get_Active_Slot_Suffix();
		unlink(Primary_Block_Device.c_str());
		symlink(Actual_Block_Device.c_str(), Primary_Block_Device.c_str()); // we create a non-slot symlink pointing to the currently selected slot which may assist zips with installing
		Is_Present = true;
		return;
	} else if (TWFunc::Path_Exists(Primary_Block_Device)) {
		Is_Present = true;
		Actual_Block_Device = Primary_Block_Device;
		return;
	}
	if (!Alternate_Block_Device.empty() && TWFunc::Path_Exists(Alternate_Block_Device)) {
		Actual_Block_Device = Alternate_Block_Device;
		Is_Present = true;
	} else {
		Is_Present = false;
	}
}

void TWPartition::Recreate_Media_Folder(void) {
	string Command;
	string Media_Path = Mount_Point + "/media";

	if (Is_FBE) {
		LOGINFO("Not recreating media folder on FBE\n");
		return;
	}
	if (!Mount(true)) {
		gui_msg(Msg(msg::kError, "recreate_folder_err=Unable to recreate {1} folder.")(Media_Path));
	} else if (!TWFunc::Path_Exists(Media_Path)) {
		PartitionManager.Mount_By_Path(Symlink_Mount_Point, true);
		LOGINFO("Recreating %s folder.\n", Media_Path.c_str());
		mkdir(Media_Path.c_str(), 0770);
		string Internal_path = DataManager::GetStrValue("tw_internal_path");
		if (!Internal_path.empty()) {
			LOGINFO("Recreating %s folder.\n", Internal_path.c_str());
			mkdir(Internal_path.c_str(), 0770);
		}
#ifdef TW_INTERNAL_STORAGE_PATH
		mkdir(EXPAND(TW_INTERNAL_STORAGE_PATH), 0770);
#endif

		// Afterwards, we will try to set the
		// default metadata that we were hopefully able to get during
		// early boot.
		tw_set_default_metadata(Media_Path.c_str());
		if (!Internal_path.empty())
			tw_set_default_metadata(Internal_path.c_str());

		// Toggle mount to ensure that "internal sdcard" gets mounted
		PartitionManager.UnMount_By_Path(Symlink_Mount_Point, true);
		PartitionManager.Mount_By_Path(Symlink_Mount_Point, true);
	}
}

void TWPartition::Recreate_AndSec_Folder(void) {
	if (!Has_Android_Secure)
		return;
	LOGINFO("Creating %s: %s\n", Backup_Display_Name.c_str(), Symlink_Path.c_str());
	if (!Mount(true)) {
		gui_msg(Msg(msg::kError, "recreate_folder_err=Unable to recreate {1} folder.")(Backup_Name));
	} else if (!TWFunc::Path_Exists(Symlink_Path)) {
		LOGINFO("Recreating %s folder.\n", Backup_Name.c_str());
		PartitionManager.Mount_By_Path(Symlink_Mount_Point, true);
		mkdir(Symlink_Path.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
		PartitionManager.UnMount_By_Path(Symlink_Mount_Point, true);
	}
}

uint64_t TWPartition::Get_Max_FileSize() {
	uint64_t maxFileSize = 0;
	const uint64_t constGB = (uint64_t) 1024 * 1024 * 1024;
	const uint64_t constTB = (uint64_t) constGB * 1024;
	const uint64_t constPB = (uint64_t) constTB * 1024;
	if (Current_File_System == "ext4")
		maxFileSize = 16 * constTB; //16 TB
	else if (Current_File_System == "vfat")
		maxFileSize = 4 * constGB; //4 GB
	else if (Current_File_System == "ntfs" || Current_File_System == "tntfs")
		maxFileSize = 256 * constTB; //256 TB
	else if (Current_File_System == "exfat")
		maxFileSize = 16 * constPB; //16 PB
	else if (Current_File_System == "ext3")
		maxFileSize = 2 * constTB; //2 TB
	else if (Current_File_System == "f2fs")
		maxFileSize = 3.94 * constTB; //3.94 TB
	else
		maxFileSize = 100000000L;
	return maxFileSize - 1;
}

bool TWPartition::Flash_Image(PartitionSettings *part_settings) {
	string Restore_File_System, full_filename;

	full_filename = part_settings->Backup_Folder + "/" + Backup_FileName;

	LOGINFO("Image filename is: %s\n", Backup_FileName.c_str());

	if (Backup_Method == BM_FILES) {
		LOGERR("Cannot flash images to file systems\n");
		return false;
	} else if (!Can_Flash_Img) {
		LOGERR("Cannot flash images to partitions %s\n", Display_Name.c_str());
		return false;
	} else {
		if (!Find_Partition_Size()) {
			LOGERR("Unable to find partition size for '%s'\n", Mount_Point.c_str());
			return false;
		}
		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, 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 == BM_DD) {
			if (!part_settings->adbbackup) {
				if (Is_Sparse_Image(full_filename)) {
					return Flash_Sparse_Image(full_filename);
				}
			}
			return Raw_Read_Write(part_settings);
		} else if (Backup_Method == BM_FLASH_UTILS) {
			return Flash_Image_FI(full_filename, NULL);
		}
	}

	LOGERR("Unknown flash method for '%s'\n", Mount_Point.c_str());
	return false;
}

bool TWPartition::Is_Sparse_Image(const string& Filename) {
	uint32_t magic = 0;
	int fd = open(Filename.c_str(), O_RDONLY);
	if (fd < 0) {
		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);
		return false;
	}
	close(fd);
	if (magic == SPARSE_HEADER_MAGIC)
		return true;
	return false;
}

bool TWPartition::Flash_Sparse_Image(const string& Filename) {
	string Command;

	gui_msg(Msg("flashing=Flashing {1}...")(Display_Name));

	Command = "simg2img '" + Filename + "' '" + Actual_Block_Device + "'";
	LOGINFO("Flash command: '%s'\n", Command.c_str());
	TWFunc::Exec_Cmd(Command);
	return true;
}

bool TWPartition::Flash_Image_FI(const string& Filename, ProgressTracking *progress) {
	string Command;
	unsigned long long file_size;

	gui_msg(Msg("flashing=Flashing {1}...")(Display_Name));
	if (progress) {
		file_size = (unsigned long long)(TWFunc::Get_File_Size(Filename));
		progress->SetPartitionSize(file_size);
	}
	// Sometimes flash image doesn't like to flash due to the first 2KB matching, so we erase first to ensure that it flashes
	Command = "erase_image " + MTD_Name;
	LOGINFO("Erase command: '%s'\n", Command.c_str());
	TWFunc::Exec_Cmd(Command);
	Command = "flash_image " + MTD_Name + " '" + Filename + "'";
	LOGINFO("Flash command: '%s'\n", Command.c_str());
	TWFunc::Exec_Cmd(Command);
	if (progress)
		progress->UpdateSize(file_size);
	return true;
}

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;

	Mount_Read_Only = true;
	if (Mount(false)) {
		Find_Actual_Block_Device();
		string temp = Actual_Block_Device;
		Find_Real_Block_Device(temp, false);
		string block = basename(temp.c_str());
		string file = "/sys/fs/" + Current_File_System + "/" + block + "/lifetime_write_kbytes";
		string result;
		if (TWFunc::Path_Exists(file)) {
			if (TWFunc::read_file(file, result) != 0) {
				LOGINFO("Check_Lifetime_Writes of '%s' failed to read_file\n", file.c_str());
			} else {
				LOGINFO("Check_Lifetime_Writes result: '%s'\n", result.c_str());
				if (result == "0") {
					ret = 0;
				}
			}
		} else {
			LOGINFO("Check_Lifetime_Writes file does not exist '%s'\n", file.c_str());
		}
		UnMount(true);
	} else {
		LOGINFO("Check_Lifetime_Writes failed to mount '%s'\n", Mount_Point.c_str());
	}
	Mount_Read_Only = original_read_only;
	return ret;
}

int TWPartition::Decrypt_Adopted() {
#ifdef TW_INCLUDE_CRYPTO
	int ret = 1;
	Is_Adopted_Storage = false;
	string Adopted_Key_File = "";

	if (!Removable)
		return ret;

	int fd = open(Alternate_Block_Device.c_str(), O_RDONLY);
	if (fd < 0) {
		LOGINFO("failed to open '%s'\n", Alternate_Block_Device.c_str());
		return ret;
	}
	char type_guid[80];
	char part_guid[80];

	if (gpt_disk_get_partition_info(fd, 2, type_guid, part_guid) == 0) {
		LOGINFO("type: '%s'\n", type_guid);
		LOGINFO("part: '%s'\n", part_guid);
		Adopted_GUID = part_guid;
		LOGINFO("Adopted_GUID '%s'\n", Adopted_GUID.c_str());
		if (strcmp(type_guid, TWGptAndroidExpand) == 0) {
			LOGINFO("android_expand found\n");
			Adopted_Key_File = "/data/misc/vold/expand_";
			Adopted_Key_File += part_guid;
			Adopted_Key_File += ".key";
			if (TWFunc::Path_Exists(Adopted_Key_File)) {
				Is_Adopted_Storage = true;
				/* Until we find a use case for this, I think it is safe
				 * to disable USB Mass Storage whenever adopted storage
				 * is present.
				 */
				LOGINFO("Detected adopted storage, disabling USB mass storage mode\n");
				DataManager::SetValue("tw_has_usb_storage", 0);
			}
		}
	}

	if (Is_Adopted_Storage) {
		string Adopted_Block_Device = Alternate_Block_Device + "p2";
		if (!TWFunc::Path_Exists(Adopted_Block_Device)) {
			Adopted_Block_Device = Alternate_Block_Device + "2";
			if (!TWFunc::Path_Exists(Adopted_Block_Device)) {
				LOGINFO("Adopted block device does not exist\n");
				goto exit;
			}
		}
		LOGINFO("key file is '%s', block device '%s'\n", Adopted_Key_File.c_str(), Adopted_Block_Device.c_str());
		char crypto_blkdev[MAXPATHLEN];
		std::string thekey;
		int fdkey = open(Adopted_Key_File.c_str(), O_RDONLY);
		if (fdkey < 0) {
			LOGINFO("failed to open key file\n");
			goto exit;
		}
		char buf[512];
		ssize_t n;
		while ((n = read(fdkey, &buf[0], sizeof(buf))) > 0) {
			thekey.append(buf, n);
		}
		close(fdkey);
		unsigned char* key = (unsigned char*) thekey.data();
		cryptfs_revert_ext_volume(part_guid);

		ret = cryptfs_setup_ext_volume(part_guid, Adopted_Block_Device.c_str(), key, thekey.size(), crypto_blkdev);
		if (ret == 0) {
			LOGINFO("adopted storage new block device: '%s'\n", crypto_blkdev);
			Decrypted_Block_Device = crypto_blkdev;
			Is_Decrypted = true;
			Is_Encrypted = true;
			Find_Actual_Block_Device();
			if (!Mount_Storage_Retry(false)) {
				LOGERR("Failed to mount decrypted adopted storage device\n");
				Is_Decrypted = false;
				Is_Encrypted = false;
				cryptfs_revert_ext_volume(part_guid);
				ret = 1;
			} else {
				UnMount(false);
				Has_Android_Secure = false;
				Symlink_Path = "";
				Symlink_Mount_Point = "";
				Backup_Name = Mount_Point.substr(1);
				Backup_Path = Mount_Point;
				TWPartition* sdext = PartitionManager.Find_Partition_By_Path("/sd-ext");
				if (sdext && sdext->Actual_Block_Device == Adopted_Block_Device) {
					LOGINFO("Removing /sd-ext from partition list due to adopted storage\n");
					PartitionManager.Remove_Partition_By_Path("/sd-ext");
				}
				Setup_Data_Media();
				Wipe_Available_in_GUI = true;
				Wipe_During_Factory_Reset = true;
				Can_Be_Backed_Up = true;
				Can_Encrypt_Backup = true;
				Use_Userdata_Encryption = true;
				Is_Storage = true;
				Storage_Name = "Adopted Storage";
				Is_SubPartition = true;
				SubPartition_Of = "/data";
				PartitionManager.Add_MTP_Storage(MTP_Storage_ID);
				DataManager::SetValue("tw_has_adopted_storage", 1);
			}
		} else {
			LOGERR("Failed to setup adopted storage decryption\n");
		}
	}
exit:
	close(fd);
	return ret;
#else
	LOGINFO("Decrypt_Adopted: no crypto support\n");
	return 1;
#endif
}

void TWPartition::Revert_Adopted() {
#ifdef TW_INCLUDE_CRYPTO
	if (!Adopted_GUID.empty()) {
		PartitionManager.Remove_MTP_Storage(Mount_Point);
		UnMount(false);
		cryptfs_revert_ext_volume(Adopted_GUID.c_str());
		Is_Adopted_Storage = false;
		Is_Encrypted = false;
		Is_Decrypted = false;
		Decrypted_Block_Device = "";
		Find_Actual_Block_Device();
		Wipe_During_Factory_Reset = false;
		Can_Be_Backed_Up = false;
		Can_Encrypt_Backup = false;
		Use_Userdata_Encryption = false;
		Is_SubPartition = false;
		SubPartition_Of = "";
		Has_Data_Media = false;
		Storage_Path = Mount_Point;
		if (!Symlink_Mount_Point.empty()) {
			TWPartition* Dat = PartitionManager.Find_Partition_By_Path("/data");
			if (Dat) {
				Dat->UnMount(false);
				Dat->Symlink_Mount_Point = Symlink_Mount_Point;
			}
			Symlink_Mount_Point = "";
		}
	}
#else
	LOGINFO("Revert_Adopted: no crypto support\n");
#endif
}

void TWPartition::Set_Backup_FileName(string fname) {
	Backup_FileName = fname;
}

string TWPartition::Get_Backup_Name() {
	return Backup_Name;
}

string TWPartition::Get_Mount_Point() {
	return Mount_Point;
}

void TWPartition::Set_Block_Device(std::string block_device) {
	Primary_Block_Device = Actual_Block_Device = block_device;
}

bool TWPartition::Get_Super_Status() {
	return Is_Super;
}

void TWPartition::Set_Can_Be_Backed_Up(bool val) {
	Can_Be_Backed_Up = val;
}

void TWPartition::Set_Can_Be_Wiped(bool val) {
	Can_Be_Wiped = val;
	Wipe_Available_in_GUI = val;
}

std::string TWPartition::Get_Backup_FileName() {
	return Backup_FileName;
}

std::string TWPartition::Get_Display_Name() {
	return Display_Name;
}

bool TWPartition::Is_SlotSelect() {
	return SlotSelect;
}

bool TWPartition::Check_Pending_Merges() {
	auto sm = android::snapshot::SnapshotManager::NewForFirstStageMount();
	if (!sm) {
		LOGERR("Unable to call snapshot manager\n");
		return false;
	}

	auto callback = [&]() -> void {
		double progress;
		sm->GetUpdateState(&progress);
		LOGINFO("waiting for merge to complete: %.2f\n", progress);
	};

	LOGINFO("checking for merges\n");
	if (!sm->HandleImminentDataWipe(callback)) {
		LOGERR("Unable to check merge status\n");
		return false;
	}
	return true;
}