Attempt to automatically identify data/media devices

Change-Id: Ia3007fbced9ce3bc94efdb3dacc582a5e68a49a4
diff --git a/data.cpp b/data.cpp
index 1ffe0f9..be85158 100644
--- a/data.cpp
+++ b/data.cpp
@@ -75,6 +75,7 @@
 #ifndef TW_NO_SCREEN_TIMEOUT
 extern blanktimer blankTimer;
 #endif
+extern bool datamedia;
 
 // Device ID functions
 void DataManager::sanitize_device_id(char* device_id) {
@@ -620,133 +621,8 @@
 	mConstValues.insert(make_pair(TW_SHOW_DUMLOCK, "0"));
 #endif
 
-#ifdef TW_INTERNAL_STORAGE_PATH
-	LOGINFO("Internal path defined: '%s'\n", EXPAND(TW_INTERNAL_STORAGE_PATH));
-	mValues.insert(make_pair(TW_USE_EXTERNAL_STORAGE, make_pair("0", 1)));
-	mConstValues.insert(make_pair(TW_HAS_INTERNAL, "1"));
-	mValues.insert(make_pair(TW_INTERNAL_PATH, make_pair(EXPAND(TW_INTERNAL_STORAGE_PATH), 0)));
-	mConstValues.insert(make_pair(TW_INTERNAL_LABEL, EXPAND(TW_INTERNAL_STORAGE_MOUNT_POINT)));
-	path.clear();
-	path = "/";
-	path += EXPAND(TW_INTERNAL_STORAGE_MOUNT_POINT);
-	mConstValues.insert(make_pair(TW_INTERNAL_MOUNT, path));
-	#ifdef TW_EXTERNAL_STORAGE_PATH
-		LOGINFO("External path defined: '%s'\n", EXPAND(TW_EXTERNAL_STORAGE_PATH));
-		// Device has dual storage
-		mConstValues.insert(make_pair(TW_HAS_DUAL_STORAGE, "1"));
-		mConstValues.insert(make_pair(TW_HAS_EXTERNAL, "1"));
-		mConstValues.insert(make_pair(TW_EXTERNAL_PATH, EXPAND(TW_EXTERNAL_STORAGE_PATH)));
-		mConstValues.insert(make_pair(TW_EXTERNAL_LABEL, EXPAND(TW_EXTERNAL_STORAGE_MOUNT_POINT)));
-		mValues.insert(make_pair(TW_ZIP_EXTERNAL_VAR, make_pair(EXPAND(TW_EXTERNAL_STORAGE_PATH), 1)));
-		path.clear();
-		path = "/";
-		path += EXPAND(TW_EXTERNAL_STORAGE_MOUNT_POINT);
-		mConstValues.insert(make_pair(TW_EXTERNAL_MOUNT, path));
-		if (strcmp(EXPAND(TW_EXTERNAL_STORAGE_PATH), "/sdcard") == 0) {
-			mValues.insert(make_pair(TW_ZIP_INTERNAL_VAR, make_pair("/emmc", 1)));
-		} else {
-			mValues.insert(make_pair(TW_ZIP_INTERNAL_VAR, make_pair("/sdcard", 1)));
-		}
-	#else
-		LOGINFO("Just has internal storage.\n");
-		// Just has internal storage
-		mValues.insert(make_pair(TW_ZIP_INTERNAL_VAR, make_pair("/sdcard", 1)));
-		mConstValues.insert(make_pair(TW_HAS_DUAL_STORAGE, "0"));
-		mConstValues.insert(make_pair(TW_HAS_EXTERNAL, "0"));
-		mConstValues.insert(make_pair(TW_EXTERNAL_PATH, "0"));
-		mConstValues.insert(make_pair(TW_EXTERNAL_MOUNT, "0"));
-		mConstValues.insert(make_pair(TW_EXTERNAL_LABEL, "0"));
-	#endif
-#else
-	#ifdef RECOVERY_SDCARD_ON_DATA
-		#ifdef TW_EXTERNAL_STORAGE_PATH
-			LOGINFO("Has /data/media + external storage in '%s'\n", EXPAND(TW_EXTERNAL_STORAGE_PATH));
-			// Device has /data/media + external storage
-			mConstValues.insert(make_pair(TW_HAS_DUAL_STORAGE, "1"));
-		#else
-			LOGINFO("Single storage only -- data/media.\n");
-			// Device just has external storage
-			mConstValues.insert(make_pair(TW_HAS_DUAL_STORAGE, "0"));
-			mConstValues.insert(make_pair(TW_HAS_EXTERNAL, "0"));
-		#endif
-	#else
-		LOGINFO("Single storage only.\n");
-		// Device just has external storage
-		mConstValues.insert(make_pair(TW_HAS_DUAL_STORAGE, "0"));
-	#endif
-	#ifdef RECOVERY_SDCARD_ON_DATA
-		LOGINFO("Device has /data/media defined.\n");
-		// Device has /data/media
-		mConstValues.insert(make_pair(TW_USE_EXTERNAL_STORAGE, "0"));
-		mConstValues.insert(make_pair(TW_HAS_INTERNAL, "1"));
-		mValues.insert(make_pair(TW_INTERNAL_PATH, make_pair("/data/media", 0)));
-		mConstValues.insert(make_pair(TW_INTERNAL_MOUNT, "/data"));
-		mConstValues.insert(make_pair(TW_INTERNAL_LABEL, "data"));
-		#ifdef TW_EXTERNAL_STORAGE_PATH
-			if (strcmp(EXPAND(TW_EXTERNAL_STORAGE_PATH), "/sdcard") == 0) {
-				mValues.insert(make_pair(TW_ZIP_INTERNAL_VAR, make_pair("/emmc", 1)));
-			} else {
-				mValues.insert(make_pair(TW_ZIP_INTERNAL_VAR, make_pair("/sdcard", 1)));
-			}
-		#else
-			mValues.insert(make_pair(TW_ZIP_INTERNAL_VAR, make_pair("/sdcard", 1)));
-		#endif
-	#else
-		LOGINFO("No internal storage defined.\n");
-		// Device has no internal storage
-		mConstValues.insert(make_pair(TW_USE_EXTERNAL_STORAGE, "1"));
-		mConstValues.insert(make_pair(TW_HAS_INTERNAL, "0"));
-		mValues.insert(make_pair(TW_INTERNAL_PATH, make_pair("0", 0)));
-		mConstValues.insert(make_pair(TW_INTERNAL_MOUNT, "0"));
-		mConstValues.insert(make_pair(TW_INTERNAL_LABEL, "0"));
-	#endif
-	#ifdef TW_EXTERNAL_STORAGE_PATH
-		LOGINFO("Only external path defined: '%s'\n", EXPAND(TW_EXTERNAL_STORAGE_PATH));
-		// External has custom definition
-		mConstValues.insert(make_pair(TW_HAS_EXTERNAL, "1"));
-		mConstValues.insert(make_pair(TW_EXTERNAL_PATH, EXPAND(TW_EXTERNAL_STORAGE_PATH)));
-		mConstValues.insert(make_pair(TW_EXTERNAL_LABEL, EXPAND(TW_EXTERNAL_STORAGE_MOUNT_POINT)));
-		mValues.insert(make_pair(TW_ZIP_EXTERNAL_VAR, make_pair(EXPAND(TW_EXTERNAL_STORAGE_PATH), 1)));
-		path.clear();
-		path = "/";
-		path += EXPAND(TW_EXTERNAL_STORAGE_MOUNT_POINT);
-		mConstValues.insert(make_pair(TW_EXTERNAL_MOUNT, path));
-	#else
-		#ifndef RECOVERY_SDCARD_ON_DATA
-			LOGINFO("No storage defined, defaulting to /sdcard.\n");
-			// Standard external definition
-			mConstValues.insert(make_pair(TW_HAS_EXTERNAL, "1"));
-			mConstValues.insert(make_pair(TW_EXTERNAL_PATH, "/sdcard"));
-			mConstValues.insert(make_pair(TW_EXTERNAL_MOUNT, "/sdcard"));
-			mConstValues.insert(make_pair(TW_EXTERNAL_LABEL, "sdcard"));
-			mValues.insert(make_pair(TW_ZIP_EXTERNAL_VAR, make_pair("/sdcard", 1)));
-		#endif
-	#endif
-#endif
-
-#ifdef TW_DEFAULT_EXTERNAL_STORAGE
-	SetValue(TW_USE_EXTERNAL_STORAGE, 1);
-	printf("TW_DEFAULT_EXTERNAL_STORAGE := true\n");
-#endif
-
-#ifdef RECOVERY_SDCARD_ON_DATA
-	if (PartitionManager.Mount_By_Path("/data", false) && TWFunc::Path_Exists("/data/media/0"))
-		SetValue(TW_INTERNAL_PATH, "/data/media/0");
-#endif
 	str = GetCurrentStoragePath();
-#ifdef RECOVERY_SDCARD_ON_DATA
-	#ifndef TW_EXTERNAL_STORAGE_PATH
-		SetValue(TW_ZIP_LOCATION_VAR, "/sdcard", 1);
-	#else
-		if (strcmp(EXPAND(TW_EXTERNAL_STORAGE_PATH), "/sdcard") == 0) {
-			SetValue(TW_ZIP_LOCATION_VAR, "/emmc", 1);
-		} else {
-			SetValue(TW_ZIP_LOCATION_VAR, "/sdcard", 1);
-		}
-	#endif
-#else
 	SetValue(TW_ZIP_LOCATION_VAR, str.c_str(), 1);
-#endif
 	str += "/TWRP/BACKUPS/";
 
 	string dev_id;
@@ -755,34 +631,6 @@
 	str += dev_id;
 	SetValue(TW_BACKUPS_FOLDER_VAR, str, 0);
 
-#ifdef SP1_DISPLAY_NAME
-	printf("SP1_DISPLAY_NAME := %s\n", EXPAND(SP1_DISPLAY_NAME));
-	if (strlen(EXPAND(SP1_DISPLAY_NAME))) mConstValues.insert(make_pair(TW_SP1_PARTITION_NAME_VAR, EXPAND(SP1_DISPLAY_NAME)));
-#else
-	#ifdef SP1_NAME
-		printf("SP1_NAME := %s\n", EXPAND(SP1_NAME));
-		if (strlen(EXPAND(SP1_NAME))) mConstValues.insert(make_pair(TW_SP1_PARTITION_NAME_VAR, EXPAND(SP1_NAME)));
-	#endif
-#endif
-#ifdef SP2_DISPLAY_NAME
-	printf("SP2_DISPLAY_NAME := %s\n", EXPAND(SP2_DISPLAY_NAME));
-	if (strlen(EXPAND(SP2_DISPLAY_NAME))) mConstValues.insert(make_pair(TW_SP2_PARTITION_NAME_VAR, EXPAND(SP2_DISPLAY_NAME)));
-#else
-	#ifdef SP2_NAME
-		printf("SP2_NAME := %s\n", EXPAND(SP2_NAME));
-		if (strlen(EXPAND(SP2_NAME))) mConstValues.insert(make_pair(TW_SP2_PARTITION_NAME_VAR, EXPAND(SP2_NAME)));
-	#endif
-#endif
-#ifdef SP3_DISPLAY_NAME
-	printf("SP3_DISPLAY_NAME := %s\n", EXPAND(SP3_DISPLAY_NAME));
-	if (strlen(EXPAND(SP3_DISPLAY_NAME))) mConstValues.insert(make_pair(TW_SP3_PARTITION_NAME_VAR, EXPAND(SP3_DISPLAY_NAME)));
-#else
-	#ifdef SP3_NAME
-		printf("SP3_NAME := %s\n", EXPAND(SP3_NAME));
-		if (strlen(EXPAND(SP3_NAME))) mConstValues.insert(make_pair(TW_SP3_PARTITION_NAME_VAR, EXPAND(SP3_NAME)));
-	#endif
-#endif
-
 	mConstValues.insert(make_pair(TW_REBOOT_SYSTEM, "1"));
 #ifdef TW_NO_REBOOT_RECOVERY
 	printf("TW_NO_REBOOT_RECOVERY := true\n");
@@ -800,8 +648,11 @@
 #ifdef RECOVERY_SDCARD_ON_DATA
 	printf("RECOVERY_SDCARD_ON_DATA := true\n");
 	mConstValues.insert(make_pair(TW_HAS_DATA_MEDIA, "1"));
+	mConstValues.insert(make_pair("tw_has_internal", "1"));
+	datamedia = true;
 #else
-	mConstValues.insert(make_pair(TW_HAS_DATA_MEDIA, "0"));
+	mValues.insert(make_pair(TW_HAS_DATA_MEDIA, make_pair("0", 0)));
+	mValues.insert(make_pair("tw_has_internal", make_pair("0", 0)));
 #endif
 #ifdef TW_NO_BATT_PERCENT
 	printf("TW_NO_BATT_PERCENT := true\n");
@@ -874,27 +725,6 @@
 #endif
 	mConstValues.insert(make_pair(TW_MIN_SYSTEM_VAR, TW_MIN_SYSTEM_SIZE));
 	mValues.insert(make_pair(TW_BACKUP_NAME, make_pair("(Auto Generate)", 0)));
-	mValues.insert(make_pair(TW_BACKUP_SYSTEM_VAR, make_pair("1", 1)));
-	mValues.insert(make_pair(TW_BACKUP_DATA_VAR, make_pair("1", 1)));
-	mValues.insert(make_pair(TW_BACKUP_BOOT_VAR, make_pair("1", 1)));
-	mValues.insert(make_pair(TW_BACKUP_RECOVERY_VAR, make_pair("0", 1)));
-	mValues.insert(make_pair(TW_BACKUP_CACHE_VAR, make_pair("0", 1)));
-	mValues.insert(make_pair(TW_BACKUP_SP1_VAR, make_pair("0", 1)));
-	mValues.insert(make_pair(TW_BACKUP_SP2_VAR, make_pair("0", 1)));
-	mValues.insert(make_pair(TW_BACKUP_SP3_VAR, make_pair("0", 1)));
-	mValues.insert(make_pair(TW_BACKUP_ANDSEC_VAR, make_pair("0", 1)));
-	mValues.insert(make_pair(TW_BACKUP_SDEXT_VAR, make_pair("0", 1)));
-	mValues.insert(make_pair(TW_BACKUP_SYSTEM_SIZE, make_pair("0", 0)));
-	mValues.insert(make_pair(TW_BACKUP_DATA_SIZE, make_pair("0", 0)));
-	mValues.insert(make_pair(TW_BACKUP_BOOT_SIZE, make_pair("0", 0)));
-	mValues.insert(make_pair(TW_BACKUP_RECOVERY_SIZE, make_pair("0", 0)));
-	mValues.insert(make_pair(TW_BACKUP_CACHE_SIZE, make_pair("0", 0)));
-	mValues.insert(make_pair(TW_BACKUP_ANDSEC_SIZE, make_pair("0", 0)));
-	mValues.insert(make_pair(TW_BACKUP_SDEXT_SIZE, make_pair("0", 0)));
-	mValues.insert(make_pair(TW_BACKUP_SP1_SIZE, make_pair("0", 0)));
-	mValues.insert(make_pair(TW_BACKUP_SP2_SIZE, make_pair("0", 0)));
-	mValues.insert(make_pair(TW_BACKUP_SP3_SIZE, make_pair("0", 0)));
-	mValues.insert(make_pair(TW_STORAGE_FREE_SIZE, make_pair("0", 0)));
 
 	mValues.insert(make_pair(TW_REBOOT_AFTER_FLASH_VAR, make_pair("0", 1)));
 	mValues.insert(make_pair(TW_SIGNED_ZIP_VERIFY_VAR, make_pair("0", 1)));
@@ -915,12 +745,6 @@
 	mValues.insert(make_pair(TW_TIME_ZONE_GUIOFFSET, make_pair("0", 1)));
 	mValues.insert(make_pair(TW_TIME_ZONE_GUIDST, make_pair("1", 1)));
 	mValues.insert(make_pair(TW_ACTION_BUSY, make_pair("0", 0)));
-	mValues.insert(make_pair(TW_BACKUP_AVG_IMG_RATE, make_pair("15000000", 1)));
-	mValues.insert(make_pair(TW_BACKUP_AVG_FILE_RATE, make_pair("3000000", 1)));
-	mValues.insert(make_pair(TW_BACKUP_AVG_FILE_COMP_RATE, make_pair("2000000", 1)));
-	mValues.insert(make_pair(TW_RESTORE_AVG_IMG_RATE, make_pair("15000000", 1)));
-	mValues.insert(make_pair(TW_RESTORE_AVG_FILE_RATE, make_pair("3000000", 1)));
-	mValues.insert(make_pair(TW_RESTORE_AVG_FILE_COMP_RATE, make_pair("2000000", 1)));
 	mValues.insert(make_pair("tw_wipe_cache", make_pair("0", 0)));
 	mValues.insert(make_pair("tw_wipe_dalvik", make_pair("0", 0)));
 	if (GetIntValue(TW_HAS_INTERNAL) == 1 && GetIntValue(TW_HAS_DATA_MEDIA) == 1 && GetIntValue(TW_HAS_EXTERNAL) == 0)
diff --git a/gui/Android.mk b/gui/Android.mk
index 113fa53..52d5f55 100644
--- a/gui/Android.mk
+++ b/gui/Android.mk
@@ -47,12 +47,6 @@
 LOCAL_CFLAGS += -D_EVENT_LOGGING
 endif
 
-ifneq ($(RECOVERY_SDCARD_ON_DATA),)
-	LOCAL_CFLAGS += -DRECOVERY_SDCARD_ON_DATA
-endif
-ifneq ($(TW_EXTERNAL_STORAGE_PATH),)
-	LOCAL_CFLAGS += -DTW_EXTERNAL_STORAGE_PATH=$(TW_EXTERNAL_STORAGE_PATH)
-endif
 ifneq ($(TW_NO_SCREEN_BLANK),)
 	LOCAL_CFLAGS += -DTW_NO_SCREEN_BLANK
 endif
diff --git a/partition.cpp b/partition.cpp
index f1d7fd2..00f84a1 100644
--- a/partition.cpp
+++ b/partition.cpp
@@ -73,6 +73,7 @@
 using namespace std;
 
 extern struct selabel_handle *selinux_handle;
+extern bool datamedia;
 
 struct flag_list {
 	const char *name;
@@ -160,6 +161,7 @@
 #ifdef TW_INCLUDE_CRYPTO_SAMSUNG
 	EcryptFS_Password = "";
 #endif
+	mtpid = 0;
 }
 
 TWPartition::~TWPartition(void) {
@@ -272,27 +274,8 @@
 			Can_Be_Backed_Up = true;
 			Can_Encrypt_Backup = true;
 			Use_Userdata_Encryption = true;
-#ifdef RECOVERY_SDCARD_ON_DATA
-			Storage_Name = "Internal Storage";
-			Has_Data_Media = true;
-			Is_Storage = true;
-			Is_Settings_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
+			if (datamedia)
+				Setup_Data_Media(0);
 #ifdef TW_INCLUDE_CRYPTO
 			Can_Be_Encrypted = true;
 			char crypto_blkdev[255];
@@ -343,14 +326,11 @@
 				// unmounted state
 				UnMount(false);
 			}
-	#ifdef RECOVERY_SDCARD_ON_DATA
-			if (!Is_Encrypted || (Is_Encrypted && Is_Decrypted))
+			if (datamedia && (!Is_Encrypted || (Is_Encrypted && Is_Decrypted)))
 				Recreate_Media_Folder();
-	#endif
 #else
-	#ifdef RECOVERY_SDCARD_ON_DATA
-			Recreate_Media_Folder();
-	#endif
+			if (datamedia)
+				Recreate_Media_Folder();
 #endif
 		} else if (Mount_Point == "/cache") {
 			Display_Name = "Cache";
@@ -702,6 +682,34 @@
 	Mount_Storage_Retry();
 }
 
+void TWPartition::Setup_Data_Media(int mtp) {
+	LOGINFO("Setting up '%s' as data/media emulated storage.\n", Mount_Point.c_str());
+	Storage_Name = "Internal Storage";
+	Has_Data_Media = true;
+	Is_Storage = true;
+	Is_Settings_Storage = true;
+	Storage_Path = "/data/media";
+	Symlink_Path = Storage_Path;
+	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("/data/media/0")) {
+		Storage_Path = "/data/media/0";
+		Symlink_Path = Storage_Path;
+		DataManager::SetValue(TW_INTERNAL_PATH, "/data/media/0");
+		UnMount(true);
+	}
+	if (mtp)
+		mtpid = mtp;
+	DataManager::SetValue("tw_has_internal", 1);
+	DataManager::SetValue("tw_has_data_media", 1);
+	du.add_absolute_dir("/data/media");
+}
+
 void TWPartition::Find_Real_Block_Device(string& Block, bool Display_Error) {
 	char device[512], realDevice[512];
 
diff --git a/partitionmanager.cpp b/partitionmanager.cpp
index af89e40..0063ff3 100644
--- a/partitionmanager.cpp
+++ b/partitionmanager.cpp
@@ -56,6 +56,8 @@
 	#endif
 #endif
 
+extern bool datamedia;
+
 TWPartitionManager::TWPartitionManager(void) {
 	mtpid = 100;
 	mtp_was_enabled = false;
@@ -100,6 +102,16 @@
 		}
 	}
 	fclose(fstabFile);
+	if (!datamedia && !settings_partition && Find_Partition_By_Path("/sdcard") == NULL && Find_Partition_By_Path("/internal_sd") == NULL && Find_Partition_By_Path("/internal_sdcard") == NULL && Find_Partition_By_Path("/emmc") == NULL) {
+		// Attempt to automatically identify /data/media emulated storage devices
+		TWPartition* Dat = Find_Partition_By_Path("/data");
+		if (Dat) {
+			LOGINFO("Using automatic handling for /data/media emulated storage device.\n");
+			datamedia = true;
+			Dat->Setup_Data_Media(++mtpid);
+			settings_partition = Dat;
+		}
+	}
 	if (!settings_partition) {
 		std::vector<TWPartition*>::iterator iter;
 		for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
@@ -168,10 +180,8 @@
 void TWPartitionManager::Setup_Android_Secure_Location(TWPartition* Part) {
 	if (Part->Has_Android_Secure)
 		Part->Setup_AndSec();
-#ifndef RECOVERY_SDCARD_ON_DATA
-	else
+	else if (!datamedia)
 		Part->Setup_AndSec();
-#endif
 }
 
 void TWPartitionManager::Output_Partition_Logging(void) {
@@ -270,9 +280,12 @@
 	if (!Part->MTD_Name.empty())
 		printf("   MTD_Name: %s\n", Part->MTD_Name.c_str());
 	string back_meth = Part->Backup_Method_By_Name();
-	printf("   Backup_Method: %s\n\n", back_meth.c_str());
+	printf("   Backup_Method: %s\n", back_meth.c_str());
 	if (Part->Mount_Flags || !Part->Mount_Options.empty())
 		printf("   Mount_Flags=0x%8x, Mount_Options=%s\n", Part->Mount_Flags, Part->Mount_Options.c_str());
+	if (Part->mtpid)
+		printf("   MTP Storage ID: %i\n", Part->mtpid);
+	printf("\n");
 }
 
 int TWPartitionManager::Mount_By_Path(string Path, bool Display_Error) {
@@ -1660,15 +1673,13 @@
 
 			// Sleep for a bit so that the device will be ready
 			sleep(1);
-#ifdef RECOVERY_SDCARD_ON_DATA
-			if (dat->Mount(false) && TWFunc::Path_Exists("/data/media/0")) {
+			if (dat->Has_Data_Media && dat->Mount(false) && TWFunc::Path_Exists("/data/media/0")) {
 				dat->Storage_Path = "/data/media/0";
 				dat->Symlink_Path = dat->Storage_Path;
 				DataManager::SetValue("tw_storage_path", "/data/media/0");
 				dat->UnMount(false);
 				Output_Partition(dat);
 			}
-#endif
 			Update_System_Details();
 			UnMount_Main_Partitions();
 		} else
@@ -1843,9 +1854,9 @@
 	TWPartition* Boot_Partition = Find_Partition_By_Path("/boot");
 
 	UnMount_By_Path("/system", true);
-#ifndef RECOVERY_SDCARD_ON_DATA
-	UnMount_By_Path("/data", true);
-#endif
+	if (!datamedia)
+		UnMount_By_Path("/data", true);
+
 	if (Boot_Partition != NULL && Boot_Partition->Can_Be_Mounted)
 		Boot_Partition->UnMount(true);
 }
diff --git a/partitions.hpp b/partitions.hpp
index 294c89e..652d733 100644
--- a/partitions.hpp
+++ b/partitions.hpp
@@ -76,6 +76,7 @@
 
 protected:
 	bool Has_Data_Media;                                                      // Indicates presence of /data/media, may affect wiping and backup methods
+	void Setup_Data_Media(int mtp);                                           // Sets up a partition as a /data/media emulated storage partition
 
 private:
 	bool Process_Fstab_Line(string Line, bool Display_Error);                 // Processes a fstab line
diff --git a/twrp.cpp b/twrp.cpp
index d9a5ab1..7361396 100644
--- a/twrp.cpp
+++ b/twrp.cpp
@@ -51,6 +51,7 @@
 
 TWPartitionManager PartitionManager;
 int Log_Offset;
+bool datamedia;
 twrpDU du;
 
 static void Print_Prop(const char *key, const char *name, void *cookie) {
@@ -76,6 +77,10 @@
 		return 0;
 	}
 
+#ifdef RECOVERY_SDCARD_ON_DATA
+	datamedia = true;
+#endif
+
 	char crash_prop_val[PROPERTY_VALUE_MAX];
 	int crash_counter;
 	property_get("twrp.crash_counter", crash_prop_val, "-1");
diff --git a/twrpDU.cpp b/twrpDU.cpp
index 0a4e44a..271dea8 100644
--- a/twrpDU.cpp
+++ b/twrpDU.cpp
@@ -33,14 +33,13 @@
 
 using namespace std;
 
+extern bool datamedia;
+
 twrpDU::twrpDU() {
-		add_relative_dir(".");
-		add_relative_dir("..");
-		add_relative_dir("lost+found");
-		add_absolute_dir("/data/data/com.google.android.music/files");
-#ifdef RECOVERY_SDCARD_ON_DATA
-		add_absolute_dir("/data/media");
-#endif
+	add_relative_dir(".");
+	add_relative_dir("..");
+	add_relative_dir("lost+found");
+	add_absolute_dir("/data/data/com.google.android.music/files");
 }
 
 void twrpDU::add_relative_dir(const string& dir) {