Adopted Storage: Add support for mixed mode sdcards

* Adds support for mixed adopted storage + removable
  storage partitioned sdcards.

* Also symlinks Adopted Storage datamedia folder to an
  available /sdcardN (N being 2 through 9) folder.

* Requires a suitable entry in fstab, for example:

    # Removable Storage
    /sd_ext ext4 /dev/block/mmcblk1p2 /dev/block/mmcblk1
        flags=storage;wipeingui;removable;encryptable=footer
    /external_sd vfat /dev/block/mmcblk1p1 /dev/block/mmcblk1
        flags=storage;wipeingui;removable;encryptable=footer

  /sd_ext will be the mountpoint for adopted storage, and /sdcardN
  will become symlinked to /sd_ext/data/media[/0]

* Fix adopted storage nickname being ""

* Output adopted partition info after successful decrypt

* Mimic single lun code for multi lun devices:
  "Mount CurrentStoragePath if it's not /data"

Change-Id: I3874c09f1a1c3a81f04277e17f17cc03ecb4184a
diff --git a/partition.cpp b/partition.cpp
index 0a858a8..71af849 100755
--- a/partition.cpp
+++ b/partition.cpp
@@ -1210,6 +1210,17 @@
 		wipe_exclusions.add_absolute_dir(Mount_Point + "/misc/vold"); // adopted storage keys
 		ExcludeAll(Mount_Point + "/system/storage.xml");
 	} else {
+		int i;
+		string path;
+		for (i = 2; i <= 9; i++) {
+			path = "/sdcard" + TWFunc::to_string(i);
+			if (!TWFunc::Path_Exists(path)) {
+				Make_Dir(path, false);
+				Symlink_Mount_Point = path;
+				LOGINFO("'%s' data/media emulated storage symlinked to %s.\n", Mount_Point.c_str(), Symlink_Mount_Point.c_str());
+				break;
+			}
+		}
 		if (Mount(true) && TWFunc::Path_Exists(Mount_Point + "/media/0")) {
 			Storage_Path = Mount_Point + "/media/0";
 			Symlink_Path = Storage_Path;
@@ -3296,7 +3307,14 @@
 	char type_guid[80];
 	char part_guid[80];
 
-	if (gpt_disk_get_partition_info(fd, 2, type_guid, part_guid) == 0) {
+	uint32_t p_num;
+	size_t last_digit = Primary_Block_Device.find_last_not_of("0123456789");
+	if ((last_digit != string::npos) && (last_digit != Primary_Block_Device.length()-1))
+		p_num = atoi(Primary_Block_Device.substr(last_digit + 1).c_str()) + 1;
+	else
+		p_num = 2;
+
+	if (gpt_disk_get_partition_info(fd, p_num, type_guid, part_guid) == 0) {
 		LOGINFO("type: '%s'\n", type_guid);
 		LOGINFO("part: '%s'\n", part_guid);
 		Adopted_GUID = part_guid;
@@ -3312,16 +3330,22 @@
 				 * to disable USB Mass Storage whenever adopted storage
 				 * is present.
 				 */
-				LOGINFO("Detected adopted storage, disabling USB mass storage mode\n");
-				DataManager::SetValue("tw_has_usb_storage", 0);
+				if (p_num == 2) {
+					// TODO: Properly detect mixed vs fully adopted storage. Maybe this
+					// should be moved to partitionmanager instead, and disable after
+					// checking all partitions. Also the presence of adopted storage does
+					// not necessarily mean it's being used as Internal Storage
+					LOGINFO("Detected adopted storage, disabling USB mass storage mode\n");
+					DataManager::SetValue("tw_has_usb_storage", 0);
+				}
 			}
 		}
 	}
 
 	if (Is_Adopted_Storage) {
-		string Adopted_Block_Device = Alternate_Block_Device + "p2";
+		string Adopted_Block_Device = Alternate_Block_Device + "p" + TWFunc::to_string(p_num);
 		if (!TWFunc::Path_Exists(Adopted_Block_Device)) {
-			Adopted_Block_Device = Alternate_Block_Device + "2";
+			Adopted_Block_Device = Alternate_Block_Device + TWFunc::to_string(p_num);
 			if (!TWFunc::Path_Exists(Adopted_Block_Device)) {
 				LOGINFO("Adopted block device does not exist\n");
 				goto exit;