/* 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>

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

#include "variables.h"
#include "common.h"
#include "partitions.hpp"
#include "data.hpp"
extern "C" {
	#include "mtdutils/mtdutils.h"
	#include "mtdutils/mounts.h"
	#include "extra-functions.h"
	int __system(const char *command);
}

TWPartition::TWPartition(void) {
	Can_Be_Mounted = false;
	Can_Be_Wiped = false;
	Wipe_During_Factory_Reset = false;
	Wipe_Available_in_GUI = false;
	Is_SubPartition = false;
	SubPartition_Of = "";
	Symlink_Path = "";
	Symlink_Mount_Point = "";
	Mount_Point = "";
	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;
	Is_Storage = false;
	Storage_Path = "";
	Current_File_System = "";
	Fstab_File_System = "";
	Format_Block_Size = 0;
}

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';
	}
	string mount_pt(full_line);
	Mount_Point = mount_pt;
	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") {
				Primary_Block_Device = ptr;
				Find_MTD_Block_Device(Primary_Block_Device);
			} 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;
			} 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\n", ptr, index);
			}
		}
		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;
			MTD_Name = "system";
		} else if (Mount_Point == "/data") {
			Display_Name = "Data";
			Wipe_Available_in_GUI = true;
			Wipe_During_Factory_Reset = true;
			MTD_Name = "userdata";
#ifdef RECOVERY_SDCARD_ON_DATA
			Has_Data_Media = true;
			Is_Storage = true;
			Storage_Path = "/data/media";
			if (strcmp(EXPAND(TW_EXTERNAL_STORAGE_PATH), "/sdcard") == 0) {
				Make_Dir("/emmc", Display_Error);
				Symlink_Path = "/data/media";
				Symlink_Mount_Point = "/emmc";
			} else {
				Make_Dir("/sdcard", Display_Error);
				Symlink_Path = "/data/media";
				Symlink_Mount_Point = "/sdcard";
			}
#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;
				DataManager::SetValue(TW_IS_ENCRYPTED, 1);
				DataManager::SetValue(TW_CRYPTO_PASSWORD, "");
				DataManager::SetValue("tw_crypto_display", "");
			}
#endif
		} else if (Mount_Point == "/cache") {
			Display_Name = "Cache";
			Wipe_Available_in_GUI = true;
			Wipe_During_Factory_Reset = true;
			Update_Size(Display_Error);
			MTD_Name = "cache";
		} 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;
		} else
			Update_Size(Display_Error);
	} else if (Is_Image(Fstab_File_System)) {
		Find_Actual_Block_Device();
		Setup_Image(Display_Error);
		if (Mount_Point == "/boot") {
			MTD_Name = "boot";
			int backup_display_size = (int)(Backup_Size / 1048576LLU);
			DataManager::SetValue(TW_BACKUP_BOOT_SIZE, backup_display_size);
			if (Backup_Size == 0) {
				DataManager::SetValue(TW_HAS_BOOT_PARTITION, 0);
				DataManager::SetValue(TW_BACKUP_BOOT_VAR, 0);
			} else
				DataManager::SetValue(TW_HAS_BOOT_PARTITION, 1);
		} else if (Mount_Point == "/recovery") {
			MTD_Name = "recovery";
			int backup_display_size = (int)(Backup_Size / 1048576LLU);
			DataManager::SetValue(TW_BACKUP_RECOVERY_SIZE, backup_display_size);
			if (Backup_Size == 0) {
				DataManager::SetValue(TW_HAS_RECOVERY_PARTITION, 0);
				DataManager::SetValue(TW_BACKUP_RECOVERY_VAR, 0);
			} else
				DataManager::SetValue(TW_HAS_RECOVERY_PARTITION, 1);
		}
	}

	// 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 += 13;
			Is_SubPartition = true;
			SubPartition_Of = ptr;
		} 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 == "auto")
		return true;
	else
		return false;
}

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

bool TWPartition::Make_Dir(string Path, bool Display_Error) {
	if (!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 (Fstab_File_System == "emmc")
		Backup_Method = DD;
	else if (Fstab_File_System == "mtd")
		Backup_Method = FLASH_UTILS;
	else
		LOGI("Unhandled file system '%s' on image '%s'\n", Fstab_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::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;
	}
}

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;

	if (!Mount(Display_Error))
		return false;

	min_len = Actual_Block_Device.size() + 2;
	sprintf(command, "df %s > /tmp/dfoutput.txt", Mount_Point.c_str());
	__system(command);
	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;
			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::Get_Folder_Size(string Path, bool Display_Error) {
	DIR* d;
	struct dirent* de;
	struct stat st;
	char path2[1024], filename[1024];
	unsigned long long dusize = 0;

	// Make a copy of path in case the data in the pointer gets overwritten later
	strcpy(path2, Path.c_str());

	d = opendir(path2);
	if (d == NULL)
	{
		LOGE("error opening '%s'\n", path2);
		return 0;
	}

	while ((de = readdir(d)) != NULL)
	{
		if (de->d_type == DT_DIR && strcmp(de->d_name, ".") != 0 && strcmp(de->d_name, "..") != 0)
		{
			strcpy(filename, path2);
			strcat(filename, "/");
			strcat(filename, de->d_name);
			dusize += Get_Folder_Size(filename, Display_Error);
		}
		else if (de->d_type == DT_REG)
		{
			strcpy(filename, path2);
			strcat(filename, "/");
			strcat(filename, de->d_name);
			stat(filename, &st);
			dusize += (unsigned long long)(st.st_size);
		}
	}
	closedir(d);

	return dusize;
}

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::Path_Exists(string Path) {
	// Check to see if the Path exists
	struct statfs st;

	if (statfs(Path.c_str(), &st) != 0)
		return false;
	else
		return true;
}

void TWPartition::Flip_Block_Device(void) {
	string temp;

	temp = Alternate_Block_Device;
	Primary_Block_Device = Alternate_Block_Device;
	Alternate_Block_Device = temp;
}

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) {
	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 (mount(Actual_Block_Device.c_str(), Mount_Point.c_str(), Current_File_System.c_str(), 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());
		return false;
	} else {
		if (Removable)
			Update_Size(Display_Error);

		if (!Symlink_Mount_Point.empty()) {
			string Command;

			Command = "mount " + Symlink_Path + " " + Symlink_Mount_Point;
			__system(Command.c_str());
		}
		return true;
	}
	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

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

		if (umount(Mount_Point.c_str()) != 0) {
			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() {
	if (!Can_Be_Wiped) {
		LOGE("Partition '%s' cannot be wiped.\n", Mount_Point.c_str());
		return false;
	}

	if (Has_Data_Media)
		return Wipe_Data_Without_Wiping_Media();

	int check;
	DataManager::GetValue(TW_RM_RF_VAR, check);
	if (check)
		return Wipe_RMRF();

	if (Current_File_System == "ext4")
		return Wipe_EXT4();

	if (Current_File_System == "ext2" || Current_File_System == "ext3")
		return Wipe_EXT23();

	if (Current_File_System == "vfat")
		return Wipe_FAT();

	if (Current_File_System == "yaffs2")
		return Wipe_MTD();

	LOGE("Unable to wipe '%s' -- unknown file system '%s'\n", Mount_Point.c_str(), Current_File_System.c_str());
	return false;
}

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::Restore(string restore_folder) {
	if (Backup_Method == FILES)
		return Restore_Tar(restore_folder);
	else if (Backup_Method == DD)
		return Restore_DD(restore_folder);
	else if (Backup_Method == FLASH_UTILS)
		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;

	Current_File_System = Fstab_File_System;
	Is_Encrypted = false;
	Is_Decrypted = false;
	Decrypted_Block_Device = "";
	Has_Data_Media = false;
	if (Wipe()) {
		Has_Data_Media = Save_Data_Media;
		if (Has_Data_Media && !Symlink_Mount_Point.empty()) {
			Recreate_Media_Folder();
		}
		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() {
	FILE *fp;
	string blkCommand;
	char blkOutput[255];
	char* blk;
	char* arg;
	char* ptr;

	if (Fstab_File_System == "yaffs2" || Fstab_File_System == "mtd")
		return; // Running blkid on some mtd devices causes a massive crash

	Find_Actual_Block_Device();
	blkCommand = "blkid " + Actual_Block_Device + " > /tmp/blkidoutput.txt";

	__system(blkCommand.c_str());
	fp = fopen("/tmp/blkidoutput.txt", "rt");
	while (fgets(blkOutput, sizeof(blkOutput), fp) != NULL)
	{
		blk = blkOutput;
		ptr = blkOutput;
		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)  break;
			}

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

		if (arg && strlen(arg) > 7)
		{
			arg += 6;   // Skip the TYPE=" portion
			arg[strlen(arg)-1] = '\0';  // Drop the tail quote
		}
		else
			continue;

		if (strcmp(Current_File_System.c_str(), arg) != 0) {
			LOGI("'%s' was '%s' now set to '%s'\n", Mount_Point.c_str(), Current_File_System.c_str(), arg);
			Current_File_System = arg;
		}
	}
	__pclose(fp);
	return;
}

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

	if (Path_Exists("/sbin/mke2fs")) {
		char command[512];

		ui_print("Formatting %s using mke2fs...\n", Display_Name.c_str());
		Find_Actual_Block_Device();
		sprintf(command, "mke2fs -t %s -m 0 %s", Current_File_System.c_str(), Actual_Block_Device.c_str());
		LOGI("mke2fs command: %s\n", command);
		if (__system(command) == 0) {
			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 (Path_Exists("/sbin/make_ext4fs")) {
		string Command;

		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 (__system(Command.c_str()) == 0) {
			ui_print("Done.\n");
			return true;
		} else {
			LOGE("Unable to wipe '%s'.\n", Mount_Point.c_str());
			return false;
		}
	} else
		return Wipe_EXT23();

	return false;
}

bool TWPartition::Wipe_FAT() {
	char command[512];

	if (Backup_Name == "and-sec") // Don't format if it's android secure
		return Wipe_RMRF();

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

		ui_print("Formatting %s using mkdosfs...\n", Display_Name.c_str());
		Find_Actual_Block_Device();
		sprintf(command,"mkdosfs %s", Actual_Block_Device.c_str()); // use mkdosfs to format it
		if (__system(command) == 0) {
			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_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;
    }
	ui_print("Done.\n");
    return true;
}

bool TWPartition::Wipe_RMRF() {
	char cmd[512];

	if (!Mount(true))
		return false;

	if (Backup_Name == "and-sec") {
		ui_print("Using rm -rf on .android_secure\n");
		sprintf(cmd, "rm -rf %s/.android_secure/* && rm -rf %s/.android_secure/.*", Mount_Point.c_str(), Mount_Point.c_str());
	} else {
		ui_print("Using rm -rf on '%s'\n", Mount_Point.c_str());
		sprintf(cmd, "rm -rf %s/* && rm -rf %s/.*", Mount_Point.c_str(), Mount_Point.c_str());
	}

	LOGI("rm -rf command is: '%s'\n", cmd);
	__system(cmd);
    return true;
}

bool TWPartition::Wipe_Data_Without_Wiping_Media() {
	char cmd[256];

	// 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");
	__system("rm -f /data/*");
	__system("rm -f /data/.*");

	DIR* d;
	d = opendir("/data");
	if (d != NULL)
	{
		struct dirent* de;
		while ((de = readdir(d)) != NULL) {
			if (strcmp(de->d_name, "media") == 0)   continue;

			sprintf(cmd, "rm -fr /data/%s", de->d_name);
			__system(cmd);
		}
		closedir(d);
	}
	ui_print("Done.\n");
	return true;
}

bool TWPartition::Backup_Tar(string backup_folder) {
	LOGI("STUB TWPartition::Backup_Tar, backup_folder: '%s'\n", backup_folder.c_str());
	return 1;
}

bool TWPartition::Backup_DD(string backup_folder) {
	LOGI("STUB TWPartition::Backup_DD, backup_folder: '%s'\n", backup_folder.c_str());
	return 1;
}

bool TWPartition::Backup_Dump_Image(string backup_folder) {
	LOGI("STUB TWPartition::Backup_Dump_Image, backup_folder: '%s'\n", backup_folder.c_str());
	return 1;
}

bool TWPartition::Restore_Tar(string restore_folder) {
	LOGI("STUB TWPartition::Restore_Tar, backup_folder: '%s'\n", restore_folder.c_str());
	return 1;
}

bool TWPartition::Restore_DD(string restore_folder) {
	LOGI("STUB TWPartition::Restore_DD, backup_folder: '%s'\n", restore_folder.c_str());
	return 1;
}

bool TWPartition::Restore_Flash_Image(string restore_folder) {
	LOGI("STUB TWPartition::Restore_Flash_Image, backup_folder: '%s'\n", restore_folder.c_str());
	// might erase image first just to ensure that it flashes
	return 1;
}

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

	if (!Can_Be_Mounted)
		return false;

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

	if (Has_Data_Media) {
		if (Mount(Display_Error)) {
			unsigned long long data_media_used, actual_data;
			data_media_used = 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
			return false;
	}
	return true;
}

void TWPartition::Find_Actual_Block_Device(void) {
	if (Is_Decrypted) {
		Actual_Block_Device = Decrypted_Block_Device;
		if (Path_Exists(Primary_Block_Device))
			Is_Present = true;
	} else if (Path_Exists(Primary_Block_Device)) {
		Is_Present = true;
		Actual_Block_Device = Primary_Block_Device;
	} else if (!Alternate_Block_Device.empty() && Path_Exists(Alternate_Block_Device)) {
		Flip_Block_Device();
		Actual_Block_Device = Primary_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 {
		LOGI("Recreating /data/media folder.\n");
		__system("cd /data && mkdir media && chmod 755 media");
		Command = "umount " + Symlink_Mount_Point;
		__system(Command.c_str());
		Command = "mount " + Symlink_Path + " " + Symlink_Mount_Point;
		__system(Command.c_str());
	}
}