Add ntfs-3g support

Add support for mounting ntfs via ntfs-3g and support for wiping
and repairing ntfs partitions.

Change-Id: I82dc4626f459bb93b86eb9ebba64ad3a6560781b
diff --git a/partition.cpp b/partition.cpp
index 6c5cf53..e612be3 100644
--- a/partition.cpp
+++ b/partition.cpp
@@ -974,6 +974,20 @@
 		}
 	}
 
+	if (Current_File_System == "ntfs" && TWFunc::Path_Exists("/sbin/ntfs-3g")) {
+		string cmd;
+		if (Mount_Read_Only)
+			cmd = "/sbin/ntfs-3g -o ro " + Actual_Block_Device + " " + Mount_Point;
+		else
+			cmd = "/sbin/ntfs-3g " + Actual_Block_Device + " " + Mount_Point;
+		LOGINFO("cmd: '%s'\n", cmd.c_str());
+		if (TWFunc::Exec_Cmd(cmd) == 0) {
+			return true;
+		} else {
+			LOGINFO("ntfs-3g failed to mount, trying regular mount method.\n");
+		}
+	}
+
 	if (Mount_Read_Only)
 		flags |= MS_RDONLY;
 
@@ -1126,6 +1140,8 @@
 			wiped = Wipe_MTD();
 		else if (New_File_System == "f2fs")
 			wiped = Wipe_F2FS();
+		else if (New_File_System == "ntfs")
+			wiped = Wipe_NTFS();
 		else {
 			LOGERR("Unable to wipe '%s' -- unknown file system '%s'\n", Mount_Point.c_str(), New_File_System.c_str());
 			unlink("/.layout_version");
@@ -1195,6 +1211,8 @@
 		return true;
 	else if (Current_File_System == "f2fs" && TWFunc::Path_Exists("/sbin/fsck.f2fs"))
 		return true;
+	else if (Current_File_System == "ntfs" && TWFunc::Path_Exists("/sbin/ntfsfix"))
+		return true;
 	return false;
 }
 
@@ -1277,6 +1295,25 @@
 			return false;
 		}
 	}
+	if (Current_File_System == "ntfs") {
+		if (!TWFunc::Path_Exists("/sbin/ntfsfix")) {
+			gui_print("ntfsfix does not exist! Cannot repair!\n");
+			return false;
+		}
+		if (!UnMount(true))
+			return false;
+		gui_print("Repairing %s using ntfsfix...\n", Display_Name.c_str());
+		Find_Actual_Block_Device();
+		command = "/sbin/ntfsfix " + Actual_Block_Device;
+		LOGINFO("Repair command: %s\n", command.c_str());
+		if (TWFunc::Exec_Cmd(command) == 0) {
+			gui_print("Done.\n");
+			return true;
+		} else {
+			LOGERR("Unable to repair '%s'.\n", Mount_Point.c_str());
+			return false;
+		}
+	}
 	return false;
 }
 
@@ -1768,6 +1805,29 @@
 	return false;
 }
 
+bool TWPartition::Wipe_NTFS() {
+	string command;
+
+	if (TWFunc::Path_Exists("/sbin/mkntfs")) {
+		if (!UnMount(true))
+			return false;
+
+		gui_print("Formatting %s using mkntfs...\n", Display_Name.c_str());
+		Find_Actual_Block_Device();
+		command = "mkntfs " + Actual_Block_Device;
+		if (TWFunc::Exec_Cmd(command) == 0) {
+			Recreate_AndSec_Folder();
+			gui_print("Done.\n");
+			return true;
+		} else {
+			LOGERR("Unable to wipe '%s'.\n", Mount_Point.c_str());
+			return false;
+		}
+		return true;
+	}
+	return false;
+}
+
 bool TWPartition::Wipe_Data_Without_Wiping_Media() {
 #ifdef TW_OEM_BUILD
 	// In an OEM Build we want to do a full format