Add android_secure support
diff --git a/partition.cpp b/partition.cpp
index 341dee7..0636039 100644
--- a/partition.cpp
+++ b/partition.cpp
@@ -55,6 +55,7 @@
 	Symlink_Path = "";
 	Symlink_Mount_Point = "";
 	Mount_Point = "";
+	Backup_Path = "";
 	Actual_Block_Device = "";
 	Primary_Block_Device = "";
 	Alternate_Block_Device = "";
@@ -75,6 +76,7 @@
 	MTD_Name = "";
 	Backup_Method = NONE;
 	Has_Data_Media = false;
+	Has_Android_Secure = false;
 	Is_Storage = false;
 	Storage_Path = "";
 	Current_File_System = "";
@@ -100,6 +102,7 @@
 	}
 	string mount_pt(full_line);
 	Mount_Point = mount_pt;
+	Backup_Path = Mount_Point;
 	index = Mount_Point.size();
 	while (index < line_len) {
 		while (index < line_len && full_line[index] == '\0')
@@ -231,17 +234,26 @@
 			Is_Storage = true;
 			Storage_Path = "/sdcard";
 			Removable = true;
+#ifndef RECOVERY_SDCARD_ON_DATA
+			Setup_AndSec();
+#endif
 		}
 #endif
 #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();
+#endif
 		}
 #else
 		if (Mount_Point == "/emmc") {
 			Is_Storage = true;
 			Storage_Path = "/emmc";
+#ifndef RECOVERY_SDCARD_ON_DATA
+			Setup_AndSec();
+#endif
 		}
 #endif
 	} else if (Is_Image(Fstab_File_System)) {
@@ -405,6 +417,16 @@
 	}
 }
 
+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];
 
@@ -527,6 +549,7 @@
 		} 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);
@@ -693,6 +716,23 @@
 	return false;
 }
 
+bool TWPartition::Wipe_AndSec(void) {
+	if (!Has_Android_Secure)
+		return false;
+
+	char cmd[512];
+
+	if (!Mount(true))
+		return false;
+
+	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());
+
+	LOGI("rm -rf command is: '%s'\n", cmd);
+	system(cmd);
+    return true;
+}
+
 bool TWPartition::Backup(string backup_folder) {
 	if (Backup_Method == FILES)
 		return Backup_Tar(backup_folder);
@@ -876,6 +916,7 @@
 		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) {
+			Recreate_AndSec_Folder();
 			ui_print("Done.\n");
 			return true;
 		} else {
@@ -908,6 +949,7 @@
 		Command += " " + Actual_Block_Device;
 		LOGI("make_ext4fs command: %s\n", Command.c_str());
 		if (system(Command.c_str()) == 0) {
+			Recreate_AndSec_Folder();
 			ui_print("Done.\n");
 			return true;
 		} else {
@@ -923,9 +965,6 @@
 bool TWPartition::Wipe_FAT() {
 	char command[512];
 
-	if (Backup_Name == "and-sec") // Don't format if it's android secure
-		return Wipe_RMRF();
-
 	if (TWFunc::Path_Exists("/sbin/mkdosfs")) {
 		if (!UnMount(true))
 			return false;
@@ -934,6 +973,7 @@
 		Find_Actual_Block_Device();
 		sprintf(command,"mkdosfs %s", Actual_Block_Device.c_str()); // use mkdosfs to format it
 		if (system(command) == 0) {
+			Recreate_AndSec_Folder();
 			ui_print("Done.\n");
 			return true;
 		} else {
@@ -975,6 +1015,7 @@
         LOGE("Failed to close '%s'", MTD_Name.c_str());
         return false;
     }
+	Recreate_AndSec_Folder();
 	ui_print("Done.\n");
     return true;
 }
@@ -985,16 +1026,12 @@
 	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());
-	}
+	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);
+	Recreate_AndSec_Folder();
     return true;
 }
 
@@ -1050,7 +1087,7 @@
 	if (Backup_Size > MAX_ARCHIVE_SIZE) {
 		// This backup needs to be split into multiple archives
 		ui_print("Breaking backup file into multiple archives...\nGenerating file lists\n");
-		sprintf(back_name, "%s", Mount_Point.c_str());
+		sprintf(back_name, "%s", Backup_Path.c_str());
 		backup_count = make_file_list(back_name);
 		if (backup_count < 1) {
 			LOGE("Error generating file list!\n");
@@ -1075,9 +1112,9 @@
 	} else {
 		Full_FileName = backup_folder + "/" + Backup_FileName;
 		if (Has_Data_Media)
-			Command = "cd " + Mount_Point + " && tar " + Tar_Args + " ./ --exclude='media*' -f '" + Full_FileName + "'";
+			Command = "cd " + Backup_Path + " && tar " + Tar_Args + " ./ --exclude='media*' -f '" + Full_FileName + "'";
 		else
-			Command = "cd " + Mount_Point + " && tar " + Tar_Args + " -f '" + Full_FileName + "' ./*";
+			Command = "cd " + Backup_Path + " && tar " + Tar_Args + " -f '" + Full_FileName + "' ./*";
 		LOGI("Backup command: '%s'\n", Command.c_str());
 		system(Command.c_str());
 	}
@@ -1143,9 +1180,14 @@
 	Restore_File_System.resize(second_period);
 	LOGI("Restore file system is: '%s'.\n", Restore_File_System.c_str());
 	Current_File_System = Restore_File_System;
-	ui_print("Wiping %s...\n", Display_Name.c_str());
-	if (!Wipe())
+	if (Has_Android_Secure) {
+		ui_print("Wiping android secure...\n");
+		if (!Wipe_AndSec())
+			return false;
+	} else if (!Wipe()) {
+		ui_print("Wiping %s...\n", Display_Name.c_str());
 		return false;
+	}
 
 	if (!Mount(true))
 		return false;
@@ -1159,7 +1201,7 @@
 		Full_FileName = restore_folder + "/" + Backup_FileName + split_index;
 		while (TWFunc::Path_Exists(Full_FileName)) {
 			ui_print("Restoring archive %i...\n", index + 1);
-			Command = "cd " + Mount_Point + " && tar -xf '" + Full_FileName + "'";
+			Command = "cd " + Backup_Path + " && tar -xf '" + Full_FileName + "'";
 			LOGI("Restore command: '%s'\n", Command.c_str());
 			system(Command.c_str());
 			index++;
@@ -1171,7 +1213,7 @@
 			return false;
 		}
 	} else {
-		Command = "cd " + Mount_Point + " && tar -xf '" + Full_FileName + "'";
+		Command = "cd " + Backup_Path + " && tar -xf '" + Full_FileName + "'";
 		LOGI("Restore command: '%s'\n", Command.c_str());
 		system(Command.c_str());
 	}
@@ -1236,6 +1278,11 @@
 			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;
+	} else if (Has_Android_Secure) {
+		if (Mount(Display_Error))
+			Backup_Size = TWFunc::Get_Folder_Size(Backup_Path, Display_Error);
+		else
+			return false;
 	}
 	return true;
 }
@@ -1270,3 +1317,21 @@
 		system(Command.c_str());
 	}
 }
+
+void TWPartition::Recreate_AndSec_Folder(void) {
+	string Command;
+
+	if (!Has_Android_Secure)
+		return;
+
+	if (!Mount(true)) {
+		LOGE("Unable to recreate android secure folder.\n");
+	} else if (!TWFunc::Path_Exists(Symlink_Path)) {
+		LOGI("Recreating android secure folder.\n");
+		TWFunc::Recursive_Mkdir(Symlink_Path);
+		Command = "umount " + Symlink_Mount_Point;
+		system(Command.c_str());
+		Command = "mount " + Symlink_Path + " " + Symlink_Mount_Point;
+		system(Command.c_str());
+	}
+}
diff --git a/partitionmanager.cpp b/partitionmanager.cpp
index 2e0219e..9685072 100644
--- a/partitionmanager.cpp
+++ b/partitionmanager.cpp
@@ -147,6 +147,8 @@
 			printf("Is_Decrypted ");
 		if (Part->Has_Data_Media)
 			printf("Has_Data_Media ");
+		if (Part->Has_Android_Secure)
+			printf("Has_Android_Secure ");
 		if (Part->Is_Storage)
 			printf("Is_Storage ");
 		printf("\n");
@@ -166,6 +168,8 @@
 			printf("   Length: %i\n", Part->Length);
 		if (!Part->Display_Name.empty())
 			printf("   Display_Name: %s\n", Part->Display_Name.c_str());
+		if (!Part->Backup_Path.empty())
+			printf("   Backup_Path: %s\n", Part->Backup_Path.c_str());
 		if (!Part->Backup_Name.empty())
 			printf("   Backup_Name: %s\n", Part->Backup_Name.c_str());
 		if (!Part->Backup_FileName.empty())
@@ -1030,30 +1034,30 @@
 		}
 
 		// Now, we just need to find the correct label
-		if (Part->Mount_Point == "/system")
+		if (Part->Backup_Path == "/system")
 			tw_restore_system = 1;
-		if (Part->Mount_Point == "/data")
+		if (Part->Backup_Path == "/data")
 			tw_restore_data = 1;
-		if (Part->Mount_Point == "/cache")
+		if (Part->Backup_Path == "/cache")
 			tw_restore_cache = 1;
-		if (Part->Mount_Point == "/recovery")
+		if (Part->Backup_Path == "/recovery")
 			tw_restore_recovery = 1;
-		if (Part->Mount_Point == "/boot")
+		if (Part->Backup_Path == "/boot")
 			tw_restore_boot = 1;
-		if (Part->Mount_Point == "/.android_secure")
+		if (Part->Backup_Path == "/and-sec")
 			tw_restore_andsec = 1;
-		if (Part->Mount_Point == "/sd-ext")
+		if (Part->Backup_Path == "/sd-ext")
 			tw_restore_sdext = 1;
 #ifdef SP1_NAME
-		if (Part->Mount_Point == TWFunc::Get_Root_Path(SP1_Name))
+		if (Part->Backup_Path == TWFunc::Get_Root_Path(SP1_Name))
 			tw_restore_sp1 = 1;
 #endif
 #ifdef SP2_NAME
-		if (Part->Mount_Point == TWFunc::Get_Root_Path(SP2_Name))
+		if (Part->Backup_Path == TWFunc::Get_Root_Path(SP2_Name))
 			tw_restore_sp2 = 1;
 #endif
 #ifdef SP3_NAME
-		if (Part->Mount_Point == TWFunc::Get_Root_Path(SP3_Name))
+		if (Part->Backup_Path == TWFunc::Get_Root_Path(SP3_Name))
 			tw_restore_sp3 = 1;
 #endif
 	}
@@ -1083,7 +1087,10 @@
 	// Iterate through all partitions
 	for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
 		if ((*iter)->Mount_Point == Local_Path || (!(*iter)->Symlink_Mount_Point.empty() && (*iter)->Symlink_Mount_Point == Local_Path)) {
-			ret = (*iter)->Wipe();
+			if (Path == "/and-sec")
+				ret = (*iter)->Wipe_AndSec();
+			else
+				ret = (*iter)->Wipe();
 			found = true;
 		} else if ((*iter)->Is_SubPartition && (*iter)->SubPartition_Of == Local_Path) {
 			(*iter)->Wipe();
@@ -1272,9 +1279,9 @@
 					DataManager::SetValue(TW_BACKUP_SDEXT_VAR, 0);
 				} else
 					DataManager::SetValue(TW_HAS_SDEXT_PARTITION, 1);
-			} else if ((*iter)->Mount_Point == "/and-sec") {
+			} else if ((*iter)->Has_Android_Secure) {
 				int backup_display_size = (int)((*iter)->Backup_Size / 1048576LLU);
-				DataManager::SetValue(TW_BACKUP_SDEXT_SIZE, backup_display_size);
+				DataManager::SetValue(TW_BACKUP_ANDSEC_SIZE, backup_display_size);
 				if ((*iter)->Backup_Size == 0) {
 					DataManager::SetValue(TW_HAS_ANDROID_SECURE, 0);
 					DataManager::SetValue(TW_BACKUP_ANDSEC_VAR, 0);
@@ -1481,23 +1488,31 @@
 		sprintf(lun_file, CUSTOM_LUN_FILE, index);
 
 		if ((fd = open(lun_file, O_WRONLY)) < 0) {
-			if (index == 0)
+			Mount_All_Storage();
+			Update_System_Details();
+			if (index == 0) {
 				LOGE("Unable to open ums lunfile '%s': (%s)", lun_file, strerror(errno));
-			return false;
+				return false;
+			} else
+				return true;
 		}
 
 		char ch = 0;
 		if (write(fd, &ch, 1) < 0) {
-			if (index == 0)
-				LOGE("Unable to write to ums lunfile '%s': (%s)", lun_file, strerror(errno));
 			close(fd);
-			return false;
+			Mount_All_Storage();
+			Update_System_Details();
+			if (index == 0) {
+				LOGE("Unable to write to ums lunfile '%s': (%s)", lun_file, strerror(errno));
+				return false;
+			} else
+				return true;
 		}
 
 		close(fd);
 	}
-	Mount_By_Path(DataManager::GetSettingsStoragePath(), true);
-	Mount_By_Path(DataManager::GetCurrentStoragePath(), true);
+	Mount_All_Storage();
+	Update_System_Details();
 	return true;
 }
 
diff --git a/partitions.hpp b/partitions.hpp
index c253d3b..e968468 100644
--- a/partitions.hpp
+++ b/partitions.hpp
@@ -50,6 +50,7 @@
 	virtual bool Mount(bool Display_Error);                                   // Mounts the partition if it is not mounted
 	virtual bool UnMount(bool Display_Error);                                 // Unmounts the partition if it is mounted
 	virtual bool Wipe();                                                      // Wipes the partition
+	virtual bool Wipe_AndSec();                                               // Wipes android secure
 	virtual bool Backup(string backup_folder);                                // Backs up the partition to the folder specified
 	virtual bool Check_MD5(string restore_folder);                            // Checks MD5 of a backup
 	virtual bool Restore(string restore_folder);                              // Restores the partition using the backup folder provided
@@ -75,6 +76,7 @@
 	string Symlink_Path;                                                      // Symlink path (e.g. /data/media)
 	string Symlink_Mount_Point;                                               // /sdcard could be the symlink mount point for /data/media
 	string Mount_Point;                                                       // Mount point for this partition (e.g. /system or /data)
+	string Backup_Path;                                                       // Path for backup
 	string Actual_Block_Device;                                               // Actual block device (one of primary, alternate, or decrypted)
 	string Primary_Block_Device;                                              // Block device (e.g. /dev/block/mmcblk1p1)
 	string Alternate_Block_Device;                                            // Alternate block device (e.g. /dev/block/mmcblk1)
@@ -95,6 +97,7 @@
 	string MTD_Name;                                                          // Name of the partition for MTD devices
 	Backup_Method_enum Backup_Method;                                         // Method used for backup
 	bool Has_Data_Media;                                                      // Indicates presence of /data/media, may affect wiping and backup methods
+	bool Has_Android_Secure;                                                  // Indicates the presence of .android_secure on this partition
 	bool Is_Storage;                                                          // Indicates if this partition is used for storage for backup, restore, and installing zips
 	string Storage_Path;                                                      // Indicates the path to the storage -- root indicates mount point, media/ indicates e.g. /data/media
 	string Current_File_System;                                               // Current file system
@@ -107,6 +110,7 @@
 	bool Is_Image(string File_System);                                        // Checks to see if the file system given is considered an image
 	void Setup_File_System(bool Display_Error);                               // Sets defaults for a file system partition
 	void Setup_Image(bool Display_Error);                                     // Sets defaults for an image partition
+	void Setup_AndSec(void);                                                  // Sets up .android_secure settings
 	void Find_Real_Block_Device(string& Block_Device, bool Display_Error);    // Checks the block device given and follows symlinks until it gets to the real block device
 	bool Find_Partition_Size();                                               // Finds the partition size from /proc/partitions
 	unsigned long long Get_Size_Via_du(string Path, bool Display_Error);      // Uses du to get sizes
@@ -114,7 +118,7 @@
 	bool Wipe_EXT23();                                                        // Formats as ext3 or ext2
 	bool Wipe_EXT4();                                                         // Formats using ext4, uses make_ext4fs when present
 	bool Wipe_FAT();                                                          // Formats as FAT except that mkdosfs from busybox usually fails so oftentimes this is actually a rm -rf wipe
-	bool Wipe_MTD();                                                       // Formats as yaffs2 for MTD memory types
+	bool Wipe_MTD();                                                          // Formats as yaffs2 for MTD memory types
 	bool Wipe_RMRF();                                                         // Uses rm -rf to wipe
 	bool Wipe_Data_Without_Wiping_Media();                                    // Uses rm -rf to wipe but does not wipe /data/media
 	bool Backup_Tar(string backup_folder);                                    // Backs up using tar for file systems
@@ -127,6 +131,7 @@
 	bool Get_Size_Via_df(bool Display_Error);                                 // Get Partition size, used, and free space using df command
 	bool Make_Dir(string Path, bool Display_Error);                           // Creates a directory if it doesn't already exist
 	bool Find_MTD_Block_Device(string MTD_Name);                              // Finds the mtd block device based on the name from the fstab
+	void Recreate_AndSec_Folder(void);                                        // Recreates the .android_secure folder
 
 friend class TWPartitionManager;
 };