/* Partition class for TWRP
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program 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 this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 *
 * The code was written from scratch by Dees_Troy dees_troy at
 * yahoo
 *
 * Copyright (c) 2012
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/vfs.h>
#include <sys/mount.h>
#include <unistd.h>
#include <dirent.h>
#include <iostream>
#include <sstream>

#ifdef TW_INCLUDE_CRYPTO
	#include "cutils/properties.h"
#endif

#include "variables.h"
#include "common.h"
#include "partitions.hpp"
#include "data.hpp"
#include "twrp-functions.hpp"
#include "twrpTar.hpp"
extern "C" {
	#include "mtdutils/mtdutils.h"
	#include "mtdutils/mounts.h"
#ifdef TW_INCLUDE_CRYPTO_SAMSUNG
	#include "crypto/libcrypt_samsung/include/libcrypt_samsung.h"
#endif
}

using namespace std;

TWPartition::TWPartition(void) {
	Can_Be_Mounted = false;
	Can_Be_Wiped = 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 = "";
	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;
	Decrypted_Block_Device = "";
	Display_Name = "";
	Backup_Name = "";
	Backup_FileName = "";
	MTD_Name = "";
	Backup_Method = NONE;
	Has_Data_Media = false;
	Has_Android_Secure = false;
	Is_Storage = false;
	Storage_Path = "";
	Current_File_System = "";
	Fstab_File_System = "";
	Format_Block_Size = 0;
	Ignore_Blkid = false;
	Retain_Layout_Version = false;
#ifdef TW_INCLUDE_CRYPTO_SAMSUNG
	EcryptFS_Password = "";
#endif
}

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

bool TWPartition::Process_Fstab_Line(string Line, bool Display_Error) {
	char full_line[MAX_FSTAB_LINE_LENGTH], item[MAX_FSTAB_LINE_LENGTH];
	int line_len = Line.size(), index = 0, item_index = 0;
	char* ptr;
	string Flags;
	strncpy(full_line, Line.c_str(), line_len);

	for (index = 0; index < line_len; index++) {
		if (full_line[index] <= 32)
			full_line[index] = '\0';
	}
	Mount_Point = full_line;
	LOGI("Processing '%s'\n", Mount_Point.c_str());
	Backup_Path = Mount_Point;
	index = Mount_Point.size();
	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 == 0) {
			// File System
			Fstab_File_System = ptr;
			Current_File_System = ptr;
			item_index++;
		} else if (item_index == 1) {
			// 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 != '/')
					LOGE("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 (Display_Error)
					LOGE("Invalid block device on '%s', '%s', %i\n", Line.c_str(), ptr, index);
				else
					LOGI("Invalid block device on '%s', '%s', %i\n", Line.c_str(), ptr, index);
				return 0;
			} else {
				Primary_Block_Device = ptr;
				Find_Real_Block_Device(Primary_Block_Device, Display_Error);
			}
			item_index++;
		} else if (item_index > 1) {
			if (*ptr == '/') {
				// 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;
				Flags = ptr;
				Process_Flags(Flags, Display_Error);
			} else if (strlen(ptr) == 4 && (strncmp(ptr, "NULL", 4) == 0 || strncmp(ptr, "null", 4) == 0 || strncmp(ptr, "null", 4) == 0)) {
				// Do nothing
			} else {
				// Unhandled data
				LOGI("Unhandled fstab information: '%s', %i, line: '%s'\n", ptr, index, Line.c_str());
			}
		}
		while (index < line_len && full_line[index] != '\0')
			index++;
	}

	if (!Is_File_System(Fstab_File_System) && !Is_Image(Fstab_File_System)) {
		if (Display_Error)
			LOGE("Unknown File System: '%s'\n", Fstab_File_System.c_str());
		else
			LOGI("Unknown File System: '%s'\n", Fstab_File_System.c_str());
		return 0;
	} else if (Is_File_System(Fstab_File_System)) {
		Find_Actual_Block_Device();
		Setup_File_System(Display_Error);
		if (Mount_Point == "/system") {
			Display_Name = "System";
			Wipe_Available_in_GUI = true;
		} else if (Mount_Point == "/data") {
			Display_Name = "Data";
			Wipe_Available_in_GUI = true;
			Wipe_During_Factory_Reset = true;
#ifdef RECOVERY_SDCARD_ON_DATA
			Has_Data_Media = true;
			Is_Storage = true;
			Storage_Path = "/data/media";
			Symlink_Path = Storage_Path;
			if (strcmp(EXPAND(TW_EXTERNAL_STORAGE_PATH), "/sdcard") == 0) {
				Make_Dir("/emmc", Display_Error);
				Symlink_Mount_Point = "/emmc";
			} else {
				Make_Dir("/sdcard", Display_Error);
				Symlink_Mount_Point = "/sdcard";
			}
			if (Mount(false) && TWFunc::Path_Exists("/data/media/0")) {
				Storage_Path = "/data/media/0";
				Symlink_Path = Storage_Path;
				DataManager::SetValue(TW_INTERNAL_PATH, "/data/media/0");
				UnMount(true);
			}
#endif
#ifdef TW_INCLUDE_CRYPTO
			Can_Be_Encrypted = true;
			char crypto_blkdev[255];
			property_get("ro.crypto.fs_crypto_blkdev", crypto_blkdev, "error");
			if (strcmp(crypto_blkdev, "error") != 0) {
				DataManager::SetValue(TW_DATA_BLK_DEVICE, Primary_Block_Device);
				DataManager::SetValue(TW_IS_DECRYPTED, 1);
				Is_Encrypted = true;
				Is_Decrypted = true;
				Decrypted_Block_Device = crypto_blkdev;
				LOGI("Data already decrypted, new block device: '%s'\n", crypto_blkdev);
			} else if (!Mount(false)) {
				Is_Encrypted = true;
				Is_Decrypted = false;
				Can_Be_Mounted = false;
				Current_File_System = "emmc";
				Setup_Image(Display_Error);
				DataManager::SetValue(TW_IS_ENCRYPTED, 1);
				DataManager::SetValue(TW_CRYPTO_PASSWORD, "");
				DataManager::SetValue("tw_crypto_display", "");
			} else {
				// Filesystem is not encrypted and the mount
				// succeeded, so get it back to the original
				// unmounted state
				UnMount(false);
			}
	#ifdef RECOVERY_SDCARD_ON_DATA
			if (!Is_Encrypted || (Is_Encrypted && Is_Decrypted))
				Recreate_Media_Folder();
	#endif
#else
	#ifdef RECOVERY_SDCARD_ON_DATA
			Recreate_Media_Folder();
	#endif
#endif
		} else if (Mount_Point == "/cache") {
			Display_Name = "Cache";
			Wipe_Available_in_GUI = true;
			Wipe_During_Factory_Reset = true;
			if (Mount(false) && !TWFunc::Path_Exists("/cache/recovery/.")) {
				LOGI("Recreating /cache/recovery folder.\n");
				if (mkdir("/cache/recovery", S_IRWXU | S_IRWXG | S_IWGRP | S_IXGRP) != 0) 
					return -1;
			}
		} else if (Mount_Point == "/datadata") {
			Wipe_During_Factory_Reset = true;
			Display_Name = "DataData";
			Is_SubPartition = true;
			SubPartition_Of = "/data";
			DataManager::SetValue(TW_HAS_DATADATA, 1);
		} else if (Mount_Point == "/sd-ext") {
			Wipe_During_Factory_Reset = true;
			Display_Name = "SD-Ext";
			Wipe_Available_in_GUI = true;
			Removable = true;
		} else if (Mount_Point == "/boot") {
			Display_Name = "Boot";
			DataManager::SetValue("tw_boot_is_mountable", 1);
		}
#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;
#else
		if (Mount_Point == "/sdcard") {
			Is_Storage = true;
			Storage_Path = "/sdcard";
			Removable = true;
#ifndef RECOVERY_SDCARD_ON_DATA
			Setup_AndSec();
			Mount_Storage_Retry();
#endif
#endif
			// blkid cannot detect exfat so we force exfat at the start if exfat support is present
			if (TWFunc::Path_Exists("/sbin/exfat-fuse") && (Fstab_File_System == "vfat" || Fstab_File_System == "auto")) {
				Fstab_File_System = "exfat";
				Current_File_System = Fstab_File_System;
			}
		}
#ifdef TW_INTERNAL_STORAGE_PATH
		if (Mount_Point == EXPAND(TW_INTERNAL_STORAGE_PATH)) {
			Is_Storage = true;
			Storage_Path = EXPAND(TW_INTERNAL_STORAGE_PATH);
#ifndef RECOVERY_SDCARD_ON_DATA
			Setup_AndSec();
			Mount_Storage_Retry();
#endif
		}
#else
		if (Mount_Point == "/emmc") {
			Is_Storage = true;
			Storage_Path = "/emmc";
#ifndef RECOVERY_SDCARD_ON_DATA
			Setup_AndSec();
			Mount_Storage_Retry();
#endif
		}
#endif
	} else if (Is_Image(Fstab_File_System)) {
		Find_Actual_Block_Device();
		Setup_Image(Display_Error);
	}

	// Process any custom flags
	if (Flags.size() > 0)
		Process_Flags(Flags, Display_Error);
	return true;
}

bool TWPartition::Process_Flags(string Flags, bool Display_Error) {
	char flags[MAX_FSTAB_LINE_LENGTH];
	int flags_len, index = 0;
	char* ptr;

	strcpy(flags, Flags.c_str());
	flags_len = Flags.size();
	for (index = 0; index < flags_len; index++) {
		if (flags[index] == ';')
			flags[index] = '\0';
	}

	index = 0;
	while (index < flags_len) {
		while (index < flags_len && flags[index] == '\0')
			index++;
		if (index >= flags_len)
			continue;
		ptr = flags + index;
		if (strcmp(ptr, "removable") == 0) {
			Removable = true;
		} else if (strcmp(ptr, "storage") == 0) {
			Is_Storage = true;
		} else if (strcmp(ptr, "canbewiped") == 0) {
			Can_Be_Wiped = true;
		} else if (strcmp(ptr, "wipeingui") == 0) {
			Can_Be_Wiped = true;
			Wipe_Available_in_GUI = true;
		} else if (strcmp(ptr, "wipeduringfactoryreset") == 0) {
			Can_Be_Wiped = true;
			Wipe_Available_in_GUI = true;
			Wipe_During_Factory_Reset = true;
		} else if (strlen(ptr) > 15 && strncmp(ptr, "subpartitionof=", 15) == 0) {
			ptr += 15;
			Is_SubPartition = true;
			SubPartition_Of = ptr;
		} else if (strcmp(ptr, "ignoreblkid") == 0) {
			Ignore_Blkid = true;
		} else if (strcmp(ptr, "retainlayoutversion") == 0) {
			Retain_Layout_Version = true;
		} else if (strlen(ptr) > 8 && strncmp(ptr, "symlink=", 8) == 0) {
			ptr += 8;
			Symlink_Path = ptr;
		} else if (strlen(ptr) > 8 && strncmp(ptr, "display=", 8) == 0) {
			ptr += 8;
			Display_Name = ptr;
		} else if (strlen(ptr) > 10 && strncmp(ptr, "blocksize=", 10) == 0) {
			ptr += 10;
			Format_Block_Size = atoi(ptr);
		} else if (strlen(ptr) > 7 && strncmp(ptr, "length=", 7) == 0) {
			ptr += 7;
			Length = atoi(ptr);
		} else {
			if (Display_Error)
				LOGE("Unhandled flag: '%s'\n", ptr);
			else
				LOGI("Unhandled flag: '%s'\n", ptr);
		}
		while (index < flags_len && flags[index] != '\0')
			index++;
	}
	return true;
}

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 == "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::Path_Exists(Path)) {
		if (mkdir(Path.c_str(), 0777) == -1) {
			if (Display_Error)
				LOGE("Can not create '%s' folder.\n", Path.c_str());
			else
				LOGI("Can not create '%s' folder.\n", Path.c_str());
			return false;
		} else {
			LOGI("Created '%s' folder.\n", Path.c_str());
			return true;
		}
	}
	return true;
}

void TWPartition::Setup_File_System(bool Display_Error) {
	struct statfs st;

	Can_Be_Mounted = true;
	Can_Be_Wiped = true;

	// Make the mount point folder if it doesn't exist
	Make_Dir(Mount_Point, Display_Error);
	Display_Name = Mount_Point.substr(1, Mount_Point.size() - 1);
	Backup_Name = Display_Name;
	Backup_Method = FILES;
}

void TWPartition::Setup_Image(bool Display_Error) {
	Display_Name = Mount_Point.substr(1, Mount_Point.size() - 1);
	Backup_Name = Display_Name;
	if (Current_File_System == "emmc")
		Backup_Method = DD;
	else if (Current_File_System == "mtd" || Current_File_System == "bml")
		Backup_Method = FLASH_UTILS;
	else
		LOGI("Unhandled file system '%s' on image '%s'\n", Current_File_System.c_str(), Display_Name.c_str());
	if (Find_Partition_Size()) {
		Used = Size;
		Backup_Size = Size;
	} else {
		if (Display_Error)
			LOGE("Unable to find parition size for '%s'\n", Mount_Point.c_str());
		else
			LOGI("Unable to find parition size for '%s'\n", Mount_Point.c_str());
	}
}

void TWPartition::Setup_AndSec(void) {
	Backup_Name = "and-sec";
	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();
}

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

	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)
			LOGE("Invalid symlink path '%s' found on block device '%s'\n", device, Block.c_str());
		else
			LOGI("Invalid symlink path '%s' found on block device '%s'\n", device, Block.c_str());
		return;
	} else {
		Block = device;
		return;
	}
}

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

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

	fp = fopen("/proc/mtd", "rt");
	if (fp == NULL) {
		LOGE("Device does not support /proc/mtd\n");
		return false;
	}

	while (fgets(line, sizeof(line), fp) != NULL)
	{
		char device[32], label[32];
		unsigned long size = 0;
		char* fstype = NULL;
		int deviceId;

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

		// Skip header and blank lines
		if ((strcmp(device, "dev:") == 0) || (strlen(line) < 8))
			continue;

		// Strip off the trailing " from the label
		label[strlen(label)-1] = '\0';

		if (strcmp(label, MTD_Name.c_str()) == 0) {
			// We found our device
			// Strip off the trailing : from the device
			device[strlen(device)-1] = '\0';
			if (sscanf(device,"mtd%d", &deviceId) == 1) {
				sprintf(device, "/dev/block/mtdblock%d", deviceId);
				Primary_Block_Device = device;
			}
		}
	}
	fclose(fp);

	return false;
}

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

	if (!Mount(Display_Error))
		return false;

	if (statfs(Local_Path.c_str(), &st) != 0) {
		if (!Removable) {
			if (Display_Error)
				LOGE("Unable to statfs '%s'\n", Local_Path.c_str());
			else
				LOGI("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;
	string result;

	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, result);
	fp = fopen("/tmp/dfoutput.txt", "rt");
	if (fp == NULL) {
		LOGI("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;
}

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

	// 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];
		char tmpString[64];

		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::Mount(bool Display_Error) {
	int exfat_mounted = 0;

	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("/sbin/exfat-fuse")) {
		string cmd = "/sbin/exfat-fuse " + Actual_Block_Device + " " + Mount_Point;
		LOGI("cmd: %s\n", cmd.c_str());
		string result;
		if (TWFunc::Exec_Cmd(cmd, result) != 0) {
			LOGI("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 (Fstab_File_System == "yaffs2") {
		// mount an MTD partition as a YAFFS2 filesystem.
		mtd_scan_partitions();
		const MtdPartition* partition;
		partition = mtd_find_partition_by_name(MTD_Name.c_str());
		if (partition == NULL) {
			LOGE("Failed to find '%s' partition to mount at '%s'\n",
			MTD_Name.c_str(), Mount_Point.c_str());
			return false;
		}
		if (mtd_mount_partition(partition, Mount_Point.c_str(), Fstab_File_System.c_str(), 0)) {
			if (Display_Error)
				LOGE("Failed to mount '%s' (MTD)\n", Mount_Point.c_str());
			else
				LOGI("Failed to mount '%s' (MTD)\n", Mount_Point.c_str());
			return false;
		} else
			return true;
	} else if (!exfat_mounted && mount(Actual_Block_Device.c_str(), Mount_Point.c_str(), Current_File_System.c_str(), 0, NULL) != 0) {
#ifdef TW_NO_EXFAT_FUSE
		if (Current_File_System == "exfat") {
			LOGI("Mounting exfat failed, trying vfat...\n");
			if (mount(Actual_Block_Device.c_str(), Mount_Point.c_str(), "vfat", 0, NULL) != 0) {
				if (Display_Error)
					LOGE("Unable to mount '%s'\n", Mount_Point.c_str());
				else
					LOGI("Unable to mount '%s'\n", Mount_Point.c_str());
				LOGI("Actual block device: '%s', current file system: '%s'\n", Actual_Block_Device.c_str(), Current_File_System.c_str());
				return false;
			}
		} else {
#endif
			if (Display_Error)
				LOGE("Unable to mount '%s'\n", Mount_Point.c_str());
			else
				LOGI("Unable to mount '%s'\n", Mount_Point.c_str());
			LOGI("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
	}
#ifdef TW_INCLUDE_CRYPTO_SAMSUNG
	string MetaEcfsFile = EXPAND(TW_EXTERNAL_STORAGE_PATH);
	MetaEcfsFile += "/.MetaEcfsFile";
	if (EcryptFS_Password.size() > 0 && PartitionManager.Mount_By_Path("/data", false) && TWFunc::Path_Exists(MetaEcfsFile)) {
		if (mount_ecryptfs_drive(EcryptFS_Password.c_str(), Mount_Point.c_str(), Mount_Point.c_str(), 0) != 0) {
			if (Display_Error)
				LOGE("Unable to mount ecryptfs for '%s'\n", Mount_Point.c_str());
			else
				LOGI("Unable to mount ecryptfs for '%s'\n", Mount_Point.c_str());
		} else {
			LOGI("Successfully mounted ecryptfs for '%s'\n", Mount_Point.c_str());
			Is_Decrypted = true;
		}
	} else {
		Is_Decrypted = false;
	}
#endif
	if (Removable)
		Update_Size(Display_Error);

	if (!Symlink_Mount_Point.empty()) {
		string Command, Result;
		Command = "mount '" + Symlink_Path + "' '" + Symlink_Mount_Point + "'";
		TWFunc::Exec_Cmd(Command, Result);
	}
	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 == "/system")
			return true; // Never unmount system if you're not supposed to unmount it

#ifdef TW_INCLUDE_CRYPTO_SAMSUNG
		if (EcryptFS_Password.size() > 0) {
			if (unmount_ecryptfs_drive(Mount_Point.c_str()) != 0) {
				if (Display_Error)
					LOGE("Unable to unmount ecryptfs for '%s'\n", Mount_Point.c_str());
				else
					LOGI("Unable to unmount ecryptfs for '%s'\n", Mount_Point.c_str());
			} else {
				LOGI("Successfully unmounted ecryptfs for '%s'\n", Mount_Point.c_str());
			}
		}
#endif

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

		umount(Mount_Point.c_str());
		if (Is_Mounted()) {
			if (Display_Error)
				LOGE("Unable to unmount '%s'\n", Mount_Point.c_str());
			else
				LOGI("Unable to unmount '%s'\n", Mount_Point.c_str());
			return false;
		} else
			return true;
	} else {
		return true;
	}
}

bool TWPartition::Wipe(string New_File_System) {
	bool wiped = false, update_crypt = false;
	int check;
	string Layout_Filename = Mount_Point + "/.layout_version";

	if (!Can_Be_Wiped) {
		LOGE("Partition '%s' cannot be wiped.\n", Mount_Point.c_str());
		return false;
	}

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

#ifdef TW_INCLUDE_CRYPTO_SAMSUNG
	if (Mount_Point == "/data" && Mount(false)) {
		if (TWFunc::Path_Exists("/data/system/edk_p_sd"))
			TWFunc::copy_file("/data/system/edk_p_sd", "/tmp/edk_p_sd", 0600);
	}
#endif

	if (Retain_Layout_Version && Mount(false) && TWFunc::Path_Exists(Layout_Filename))
		TWFunc::copy_file(Layout_Filename, "/.layout_version", 0600);
	else
		unlink("/.layout_version");

	if (Has_Data_Media) {
		wiped = Wipe_Data_Without_Wiping_Media();
	} else {

		DataManager::GetValue(TW_RM_RF_VAR, check);

		if (check)
			wiped = Wipe_RMRF();
		else if (New_File_System == "ext4")
			wiped = Wipe_EXT4();
		else if (New_File_System == "ext2" || New_File_System == "ext3")
			wiped = Wipe_EXT23(New_File_System);
		else if (New_File_System == "vfat")
			wiped = Wipe_FAT();
		else if (New_File_System == "exfat")
			wiped = Wipe_EXFAT();
		else if (New_File_System == "yaffs2")
			wiped = Wipe_MTD();
		else {
			LOGE("Unable to wipe '%s' -- unknown file system '%s'\n", Mount_Point.c_str(), New_File_System.c_str());
			unlink("/.layout_version");
			return false;
		}
		update_crypt = wiped;
	}

	if (wiped) {
#ifdef TW_INCLUDE_CRYPTO_SAMSUNG
		if (Mount_Point == "/data" && Mount(false)) {
			if (TWFunc::Path_Exists("/tmp/edk_p_sd")) {
				Make_Dir("/data/system", true);
				TWFunc::copy_file("/tmp/edk_p_sd", "/data/system/edk_p_sd", 0600);
			}
		}
#endif

		if (Mount_Point == "/cache")
			DataManager::Output_Version();

		if (TWFunc::Path_Exists("/.layout_version") && Mount(false))
			TWFunc::copy_file("/.layout_version", Layout_Filename, 0600);

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

	ui_print("Wiping .android_secure\n");
	TWFunc::removeDir(Mount_Point + "/.android_secure/", true);
    return true;
}

bool TWPartition::Backup(string backup_folder) {
	if (Backup_Method == FILES)
		return Backup_Tar(backup_folder);
	else if (Backup_Method == DD)
		return Backup_DD(backup_folder);
	else if (Backup_Method == FLASH_UTILS)
		return Backup_Dump_Image(backup_folder);
	LOGE("Unknown backup method for '%s'\n", Mount_Point.c_str());
	return false;
}

bool TWPartition::Check_MD5(string restore_folder) {
	string Full_Filename;
	char split_filename[512];
	int index = 0;

	Full_Filename = restore_folder + "/" + Backup_FileName;
	if (!TWFunc::Path_Exists(Full_Filename)) {
		// This is a split archive, we presume
		sprintf(split_filename, "%s%03i", Full_Filename.c_str(), index);
		while (index < 1000 && TWFunc::Path_Exists(split_filename)) {
			if (TWFunc::Check_MD5(split_filename) == 0) {
				LOGE("MD5 failed to match on '%s'.\n", split_filename);
				return false;
			}
			index++;
			sprintf(split_filename, "%s%03i", Full_Filename.c_str(), index);
		}
		return true;
	} else {
		// Single file archive
		if (TWFunc::Check_MD5(Full_Filename) == 0) {
			LOGE("MD5 failed to match on '%s'.\n", split_filename);
			return false;
		} else
			return true;
	}
	return false;
}

bool TWPartition::Restore(string restore_folder) {
	size_t first_period, second_period;
	string Restore_File_System;

	TWFunc::GUI_Operation_Text(TW_RESTORE_TEXT, Display_Name, "Restoring");
	LOGI("Restore filename is: %s\n", Backup_FileName.c_str());

	// Parse backup filename to extract the file system before wiping
	first_period = Backup_FileName.find(".");
	if (first_period == string::npos) {
		LOGE("Unable to find file system (first period).\n");
		return false;
	}
	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) {
		LOGE("Unable to find file system (second period).\n");
		return false;
	}
	Restore_File_System.resize(second_period);
	LOGI("Restore file system is: '%s'.\n", Restore_File_System.c_str());

	if (Is_File_System(Restore_File_System))
		return Restore_Tar(restore_folder, Restore_File_System);
	else if (Is_Image(Restore_File_System)) {
		if (Restore_File_System == "emmc")
			return Restore_DD(restore_folder);
		else if (Restore_File_System == "mtd" || Restore_File_System == "bml")
			return Restore_Flash_Image(restore_folder);
	}

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

string TWPartition::Backup_Method_By_Name() {
	if (Backup_Method == NONE)
		return "none";
	else if (Backup_Method == FILES)
		return "files";
	else if (Backup_Method == DD)
		return "dd";
	else if (Backup_Method == FLASH_UTILS)
		return "flash_utils";
	else
		return "undefined";
	return "ERROR!";
}

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

bool TWPartition::Wipe_Encryption() {
	bool Save_Data_Media = Has_Data_Media;

	if (!UnMount(true))
		return false;

	Has_Data_Media = false;
	if (Wipe(Fstab_File_System)) {
		Has_Data_Media = Save_Data_Media;
		if (Has_Data_Media && !Symlink_Mount_Point.empty()) {
			Recreate_Media_Folder();
		}
		ui_print("You may need to reboot recovery to be able to use /data again.\n");
		return true;
	} else {
		Has_Data_Media = Save_Data_Media;
		LOGE("Unable to format to remove encryption.\n");
		return false;
	}
	return false;
}

void TWPartition::Check_FS_Type() {
	string blkCommand, result;
	string blkOutput;
	char* blk;
	char* arg;
	char* ptr;
	int type_found = 0;

	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;

	blkCommand = "blkid " + Actual_Block_Device;
	TWFunc::Exec_Cmd(blkCommand, result);
	std::stringstream line(result);	
	while (getline(line, blkOutput))
	{
		blk = (char*) blkOutput.c_str();
		ptr = (char*) blkOutput.c_str();
		while (*ptr > 32 && *ptr != ':')		ptr++;
		if (*ptr == 0)						  continue;
		*ptr = 0;

		// Increment by two, but verify that we don't hit a NULL
		ptr++;
		if (*ptr != 0)	  ptr++;

		// Now, find the TYPE field
		while (1)
		{
			arg = ptr;
			while (*ptr > 32)	   ptr++;
			if (*ptr != 0) {
				*ptr = 0;
				ptr++;
			}

			if (strlen(arg) > 6) {
				if (memcmp(arg, "TYPE=\"", 6) == 0) {
					type_found = 1;
					break;
				}
			}

			if (*ptr == 0) {
				arg = NULL;
				break;
			}
		}

		if (type_found) {
			arg += 6;   // Skip the TYPE=" portion
			arg[strlen(arg)-1] = '\0';  // Drop the tail quote
			if (Current_File_System != arg) {
				LOGI("'%s' was '%s' now set to '%s'\n", Mount_Point.c_str(), Current_File_System.c_str(), arg);
				Current_File_System = arg;
			}
		} else
			continue;
	}
	return;
}

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

	if (TWFunc::Path_Exists("/sbin/mke2fs")) {
		string command, result;

		ui_print("Formatting %s using mke2fs...\n", Display_Name.c_str());
		Find_Actual_Block_Device();
		command = "mke2fs -t " + File_System + " -m 0 " + Actual_Block_Device;
		LOGI("mke2fs command: %s\n", command.c_str());
		if (TWFunc::Exec_Cmd(command, result) == 0) {
			Current_File_System = File_System;
			Recreate_AndSec_Folder();
			ui_print("Done.\n");
			return true;
		} else {
			LOGE("Unable to wipe '%s'.\n", Mount_Point.c_str());
			return false;
		}
	} else
		return Wipe_RMRF();

	return false;
}

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

	if (TWFunc::Path_Exists("/sbin/make_ext4fs")) {
		string Command, result;

		ui_print("Formatting %s using make_ext4fs...\n", Display_Name.c_str());
		Find_Actual_Block_Device();
		Command = "make_ext4fs";
		if (!Is_Decrypted && Length != 0) {
			// Only use length if we're not decrypted
			char len[32];
			sprintf(len, "%i", Length);
			Command += " -l ";
			Command += len;
		}
		Command += " " + Actual_Block_Device;
		LOGI("make_ext4fs command: %s\n", Command.c_str());
		if (TWFunc::Exec_Cmd(Command, result) == 0) {
			Current_File_System = "ext4";
			Recreate_AndSec_Folder();
			ui_print("Done.\n");
			return true;
		} else {
			LOGE("Unable to wipe '%s'.\n", Mount_Point.c_str());
			return false;
		}
	} else
		return Wipe_EXT23("ext4");

	return false;
}

bool TWPartition::Wipe_FAT() {
	string command, result;

	if (TWFunc::Path_Exists("/sbin/mkdosfs")) {
		if (!UnMount(true))
			return false;

		ui_print("Formatting %s using mkdosfs...\n", Display_Name.c_str());
		Find_Actual_Block_Device();
		command = "mkdosfs " + Actual_Block_Device;
		if (TWFunc::Exec_Cmd(command, result) == 0) {
			Current_File_System = "vfat";
			Recreate_AndSec_Folder();
			ui_print("Done.\n");
			return true;
		} else {
			LOGE("Unable to wipe '%s'.\n", Mount_Point.c_str());
			return false;
		}
		return true;
	}
	else
		return Wipe_RMRF();

	return false;
}

bool TWPartition::Wipe_EXFAT() {
	string command, result;

	if (TWFunc::Path_Exists("/sbin/mkexfatfs")) {
		if (!UnMount(true))
			return false;

		ui_print("Formatting %s using mkexfatfs...\n", Display_Name.c_str());
		Find_Actual_Block_Device();
		command = "mkexfatfs " + Actual_Block_Device;
		if (TWFunc::Exec_Cmd(command, result) == 0) {
			Recreate_AndSec_Folder();
			ui_print("Done.\n");
			return true;
		} else {
			LOGE("Unable to wipe '%s'.\n", Mount_Point.c_str());
			return false;
		}
		return true;
	}
	return false;
}

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

	ui_print("MTD Formatting \"%s\"\n", MTD_Name.c_str());

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

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

bool TWPartition::Wipe_RMRF() {
	if (!Mount(true))
		return false;

	ui_print("Removing all files under '%s'\n", Mount_Point.c_str());
	TWFunc::removeDir(Mount_Point, true);
	Recreate_AndSec_Folder();
	return true;
}

bool TWPartition::Wipe_Data_Without_Wiping_Media() {
	string dir;

	// This handles wiping data on devices with "sdcard" in /data/media
	if (!Mount(true))
		return false;

	ui_print("Wiping data without wiping /data/media ...\n");

	DIR* d;
	d = opendir("/data");
	if (d != NULL) {
		struct dirent* de;
		while ((de = readdir(d)) != NULL) {
			if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0)   continue;
			// The media folder is the "internal sdcard"
			// The .layout_version file is responsible for determining whether 4.2 decides up upgrade
			//    the media folder for multi-user.
			if (strcmp(de->d_name, "media") == 0 || strcmp(de->d_name, ".layout_version") == 0)   continue;
			
			dir = "/data/";
			dir.append(de->d_name);
			if (de->d_type == DT_DIR) {
				TWFunc::removeDir(dir, false);
			} 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()))
					LOGI("Unable to unlink '%s'\n", dir.c_str());
			}
		}
		closedir(d);
		ui_print("Done.\n");
		return true;
	}
	ui_print("Dirent failed to open /data, error!\n");
	return false;
}

bool TWPartition::Backup_Tar(string backup_folder) {
	char back_name[255], split_index[5];
	string Full_FileName, Split_FileName, Tar_Args, Command;
	int use_compression, index, backup_count;
	struct stat st;
	unsigned long long total_bsize = 0, file_size;
	twrpTar tar;
	vector <string> files;
	
	if (!Mount(true))
		return false;

	if (Backup_Path == "/and-sec") {
		TWFunc::GUI_Operation_Text(TW_BACKUP_TEXT, "Android Secure", "Backing Up");
		ui_print("Backing up %s...\n", "Android Secure");
	} else {
		TWFunc::GUI_Operation_Text(TW_BACKUP_TEXT, Display_Name, "Backing Up");
		ui_print("Backing up %s...\n", Display_Name.c_str());
	}

	DataManager::GetValue(TW_USE_COMPRESSION_VAR, use_compression);

	sprintf(back_name, "%s.%s.win", Backup_Name.c_str(), Current_File_System.c_str());
	Backup_FileName = back_name;
	Full_FileName = backup_folder + "/" + Backup_FileName;
	 if (Backup_Size > MAX_ARCHIVE_SIZE) {
		// This backup needs to be split into multiple archives
		ui_print("Breaking backup file into multiple archives...\n");
		sprintf(back_name, "%s", Backup_Path.c_str());
		tar.setdir(back_name);
		tar.setfn(Full_FileName);
		backup_count = tar.splitArchiveThread();
		if (backup_count == -1) {
			LOGE("Error tarring split files!\n");
			return false;
		}
		return true;
	} else {
		Full_FileName = backup_folder + "/" + Backup_FileName;
		if (use_compression) {
			tar.setdir(Backup_Path);
			tar.setfn(Full_FileName);
			if (tar.createTarGZThread() != 0)
				return -1;
			string gzname = Full_FileName + ".gz";
			rename(gzname.c_str(), Full_FileName.c_str());
		}
		else {
			tar.setdir(Backup_Path);
			tar.setfn(Full_FileName);
			if (tar.createTarThread() != 0)
				return -1;
		}
		if (TWFunc::Get_File_Size(Full_FileName) == 0) {
			LOGE("Backup file size for '%s' is 0 bytes.\n", Full_FileName.c_str());
			return false;
		}
	}
	return true;
}

bool TWPartition::Backup_DD(string backup_folder) {
	char back_name[255];
	string Full_FileName, Command, result;
	int use_compression;

	TWFunc::GUI_Operation_Text(TW_BACKUP_TEXT, Display_Name, "Backing Up");
	ui_print("Backing up %s...\n", Display_Name.c_str());

	sprintf(back_name, "%s.%s.win", Backup_Name.c_str(), Current_File_System.c_str());
	Backup_FileName = back_name;

	Full_FileName = backup_folder + "/" + Backup_FileName;

	Command = "dd if=" + Actual_Block_Device + " of='" + Full_FileName + "'";
	LOGI("Backup command: '%s'\n", Command.c_str());
	TWFunc::Exec_Cmd(Command, result);
	if (TWFunc::Get_File_Size(Full_FileName) == 0) {
		LOGE("Backup file size for '%s' is 0 bytes.\n", Full_FileName.c_str());
		return false;
	}
	return true;
}

bool TWPartition::Backup_Dump_Image(string backup_folder) {
	char back_name[255];
	string Full_FileName, Command, result;
	int use_compression;

	TWFunc::GUI_Operation_Text(TW_BACKUP_TEXT, Display_Name, "Backing Up");
	ui_print("Backing up %s...\n", Display_Name.c_str());

	sprintf(back_name, "%s.%s.win", Backup_Name.c_str(), Current_File_System.c_str());
	Backup_FileName = back_name;

	Full_FileName = backup_folder + "/" + Backup_FileName;

	Command = "dump_image " + MTD_Name + " '" + Full_FileName + "'";
	LOGI("Backup command: '%s'\n", Command.c_str());
	TWFunc::Exec_Cmd(Command, result);
	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
		LOGE("Backup file size for '%s' is 0 bytes.\n", Full_FileName.c_str());
		return false;
	}
	return true;
}

bool TWPartition::Restore_Tar(string restore_folder, string Restore_File_System) {
	string Full_FileName, Command;
	int index = 0;
	char split_index[5];

	if (Has_Android_Secure) {
		ui_print("Wiping android secure...\n");
		if (!Wipe_AndSec())
			return false;
	} else {
		ui_print("Wiping %s...\n", Display_Name.c_str());
		if (!Wipe(Restore_File_System))
		    return false;
	}

	if (!Mount(true))
		return false;

	TWFunc::GUI_Operation_Text(TW_RESTORE_TEXT, Display_Name, "Restoring");
	ui_print("Restoring %s...\n", Display_Name.c_str());
	Full_FileName = restore_folder + "/" + Backup_FileName;
	if (!TWFunc::Path_Exists(Full_FileName)) {
		if (!TWFunc::Path_Exists(Full_FileName)) {
			// Backup is multiple archives
			LOGI("Backup is multiple archives.\n");
			sprintf(split_index, "%03i", index);
			Full_FileName = restore_folder + "/" + Backup_FileName + split_index;
			while (TWFunc::Path_Exists(Full_FileName)) {
				index++;
				ui_print("Restoring archive %i...\n", index);
				LOGI("Restoring '%s'...\n", Full_FileName.c_str());
				twrpTar tar;
				tar.setdir("/");
				tar.setfn(Full_FileName);
				if (tar.extractTarThread() != 0)
					return false;
				sprintf(split_index, "%03i", index);
				Full_FileName = restore_folder + "/" + Backup_FileName + split_index;
			}
			if (index == 0) {
				LOGE("Error locating restore file: '%s'\n", Full_FileName.c_str());
				return false;
			}
		}
	} else {
		twrpTar tar;
		tar.setdir(Backup_Path);
		tar.setfn(Full_FileName);
		if (tar.extractTarThread() != 0)
			return false;
	}
	return true;
}

bool TWPartition::Restore_DD(string restore_folder) {
	string Full_FileName, Command, result;

	TWFunc::GUI_Operation_Text(TW_RESTORE_TEXT, Display_Name, "Restoring");
	Full_FileName = restore_folder + "/" + Backup_FileName;

	if (!Find_Partition_Size()) {
		LOGE("Unable to find partition size for '%s'\n", Mount_Point.c_str());
		return false;
	}
	unsigned long long backup_size = TWFunc::Get_File_Size(Full_FileName);
	if (backup_size > Size) {
		LOGE("Size (%iMB) of backup '%s' is larger than target device '%s' (%iMB)\n",
			(int)(backup_size / 1048576LLU), Full_FileName.c_str(),
			Actual_Block_Device.c_str(), (int)(Size / 1048576LLU));
		return false;
	}

	ui_print("Restoring %s...\n", Display_Name.c_str());
	Command = "dd bs=4096 if='" + Full_FileName + "' of=" + Actual_Block_Device;
	LOGI("Restore command: '%s'\n", Command.c_str());
	TWFunc::Exec_Cmd(Command, result);
	return true;
}

bool TWPartition::Restore_Flash_Image(string restore_folder) {
	string Full_FileName, Command, result;

	ui_print("Restoring %s...\n", Display_Name.c_str());
	Full_FileName = restore_folder + "/" + Backup_FileName;
	// 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;
	LOGI("Erase command: '%s'\n", Command.c_str());
	TWFunc::Exec_Cmd(Command, result);
	Command = "flash_image " + MTD_Name + " '" + Full_FileName + "'";
	LOGI("Restore command: '%s'\n", Command.c_str());
	TWFunc::Exec_Cmd(Command, result);
	return true;
}

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

	if (!Can_Be_Mounted && !Is_Encrypted)
		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)) {
			unsigned long long data_media_used, actual_data;
			Used = TWFunc::Get_Folder_Size("/data", Display_Error);
			data_media_used = TWFunc::Get_Folder_Size("/data/media", Display_Error);
			actual_data = Used - data_media_used;
			Backup_Size = actual_data;
			int bak = (int)(Backup_Size / 1048576LLU);
			int total = (int)(Size / 1048576LLU);
			int us = (int)(Used / 1048576LLU);
			int fre = (int)(Free / 1048576LLU);
			int datmed = (int)(data_media_used / 1048576LLU);
			LOGI("Data backup size is %iMB, size: %iMB, used: %iMB, free: %iMB, in data/media: %iMB.\n", bak, total, us, fre, datmed);
		} else {
			if (!Was_Already_Mounted)
				UnMount(false);
			return false;
		}
	} else if (Has_Android_Secure) {
		if (Mount(Display_Error))
			Backup_Size = TWFunc::Get_Folder_Size(Backup_Path, Display_Error);
		else {
			if (!Was_Already_Mounted)
				UnMount(false);
			return false;
		}
	}
	if (!Was_Already_Mounted)
		UnMount(false);
	return true;
}

void TWPartition::Find_Actual_Block_Device(void) {
	if (Is_Decrypted) {
		Actual_Block_Device = Decrypted_Block_Device;
		if (TWFunc::Path_Exists(Primary_Block_Device))
			Is_Present = true;
	} else if (TWFunc::Path_Exists(Primary_Block_Device)) {
		Is_Present = true;
		Actual_Block_Device = Primary_Block_Device;
		return;
	}
	if (Is_Decrypted) {
	} else 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;

	if (!Mount(true)) {
		LOGE("Unable to recreate /data/media folder.\n");
	} else if (!TWFunc::Path_Exists("/data/media")) {
		PartitionManager.Mount_By_Path(Symlink_Mount_Point, true);
		LOGI("Recreating /data/media folder.\n");
		mkdir("/data/media", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); 
		PartitionManager.UnMount_By_Path(Symlink_Mount_Point, true);
	}
}

void TWPartition::Recreate_AndSec_Folder(void) {
	if (!Has_Android_Secure)
		return;
	LOGI("Creating .android_secure: %s\n", Symlink_Path.c_str());
	if (!Mount(true)) {
		LOGE("Unable to recreate android secure folder.\n");
	} else if (!TWFunc::Path_Exists(Symlink_Path)) {
		LOGI("Recreating android secure folder.\n");
		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);
	}
}
