Handle XML files format properly

In A12 format of XML files changed to Android Binary XML
TWRP uses RapidXML to parse XMLs, but it don't support ABX format
So before parse check format of XML format and if it is in ABX, just ignore it for now

Change-Id: Ie40f5b3534db50143999984be22ade1d1af162e7
diff --git a/partitionmanager.cpp b/partitionmanager.cpp
index 9e37463..b1ddb99 100755
--- a/partitionmanager.cpp
+++ b/partitionmanager.cpp
@@ -1837,23 +1837,30 @@
 			user.userId = to_string(userId);
 
 			// Attempt to get name of user. Fallback to user ID if this fails.
-			char* userFile = PageManager::LoadFileToBuffer("/data/system/users/" + to_string(userId) + ".xml", NULL);
-			if (userFile == NULL) {
-				user.userName = to_string(userId);
+			std::string path = "/data/system/users/" + to_string(userId) + ".xml";
+			if ((atoi(TWFunc::System_Property_Get("ro.build.version.sdk").c_str()) > 30) && TWFunc::Path_Exists(path)) {
+				if(!TWFunc::Check_Xml_Format(path))
+					user.userName = to_string(userId);
 			}
 			else {
-				xml_document<> *userXml = new xml_document<>();
-				userXml->parse<0>(userFile);
-				xml_node<>* userNode = userXml->first_node("user");
-				if (userNode == nullptr) {
+				char* userFile = PageManager::LoadFileToBuffer(path, NULL);
+				if (userFile == NULL) {
 					user.userName = to_string(userId);
-				} else {
-					xml_node<>* nameNode = userNode->first_node("name");
-					if (nameNode == nullptr)
+				}
+				else {
+					xml_document<> *userXml = new xml_document<>();
+					userXml->parse<0>(userFile);
+					xml_node<>* userNode = userXml->first_node("user");
+					if (userNode == nullptr) {
 						user.userName = to_string(userId);
-					else {
-						string userName = nameNode->value();
-						user.userName = userName + " (" + to_string(userId) + ")";
+					} else {
+						xml_node<>* nameNode = userNode->first_node("name");
+						if (nameNode == nullptr)
+							user.userName = to_string(userId);
+						else {
+							string userName = nameNode->value();
+							user.userName = userName + " (" + to_string(userId) + ")";
+						}
 					}
 				}
 			}
@@ -2985,6 +2992,16 @@
 		LOGERR("Cannot decrypt adopted storage because /data will not mount\n");
 		return false;
 	}
+
+	// In Android 12 xml format changed. Previously it was human-readable format with xml tags
+	// now it's ABX (Android Binary Xml). Sadly, rapidxml can't parse it, so check xml format firstly
+	std::string path = "/data/system/storage.xml";
+	if ((atoi(TWFunc::System_Property_Get("ro.build.version.sdk").c_str()) > 30) && TWFunc::Path_Exists(path))
+		if(!TWFunc::Check_Xml_Format(path)) {
+			LOGINFO("Android 12+: storage.xml is in ABX format. Skipping adopted storage decryption\n");
+			return false;
+		}
+
 	LOGINFO("Decrypt adopted storage starting\n");
 	char* xmlFile = PageManager::LoadFileToBuffer("/data/system/storage.xml", NULL);
 	xml_document<> *doc = NULL;
@@ -3595,4 +3612,4 @@
 		return false;
 	}
 	return true;
-}
\ No newline at end of file
+}
diff --git a/twrp-functions.cpp b/twrp-functions.cpp
index 782afe1..b1e9b26 100755
--- a/twrp-functions.cpp
+++ b/twrp-functions.cpp
@@ -1495,4 +1495,20 @@
 exit:
 	return TW_DEFAULT_RECOVERY_FOLDER;
 }
+
+bool TWFunc::Check_Xml_Format(const std::string filename) {
+	std::string buffer(' ', 4);
+	std::string abx_hdr("ABX\x00", 4);
+	std::ifstream File;
+	File.open(filename);
+	if (File.is_open()) {
+		File.get(&buffer[0], buffer.size());
+		File.close();
+		// Android Binary Xml start from these bytes
+		if(!buffer.compare(0, abx_hdr.size(), abx_hdr))
+			return false; // bad format, not possible to parse
+	}
+	return true; // good format, possible to parse
+}
+
 #endif // ndef BUILD_TWRPTAR_MAIN
diff --git a/twrp-functions.hpp b/twrp-functions.hpp
index 77ca1a2..89311a2 100755
--- a/twrp-functions.hpp
+++ b/twrp-functions.hpp
@@ -129,6 +129,7 @@
 	static void List_Mounts(); // List current mounts by the kernel
 	static void Clear_Bootloader_Message(); // Removes the bootloader message from misc for next boot
 	static string Check_For_TwrpFolder(); // Gets user defined path on storage where backups should be stored
+	static bool Check_Xml_Format(const std::string filename); // Return whether a xml is in plain xml or ABX format
 
 private:
 	static void Copy_Log(string Source, string Destination);