From bd386f445db0df88025a70063affc0473a1e701c Mon Sep 17 00:00:00 2001 From: Mike Fleetwood Date: Mon, 11 Jan 2021 17:26:41 +0000 Subject: [PATCH] Add exFAT support (!30) With exfatprogs (https://github.com/exfatprogs/exfatprogs) installed the following operations on exFAT file systems are supported: - Creation - Checking - Labelling As of the current exfatprogs 1.0.4 the following are not supported: - Reading usage - Resizing - Updating the UUID Closes !30 - Add exFAT support --- README | 1 + gparted.appdata.xml.in | 6 ++-- include/exfat.h | 13 +++++++-- src/Utils.cc | 3 +- src/exfat.cc | 65 ++++++++++++++++++++++++++++++++++++++++-- 5 files changed, 80 insertions(+), 8 deletions(-) diff --git a/README b/README index b0d900d9..13de9287 100644 --- a/README +++ b/README @@ -261,6 +261,7 @@ provide this support: btrfs-progs / btrfs-tools e2fsprogs + exfatprogs f2fs-tools dosfstools mtools - required to read and write FAT16/32 volume labels diff --git a/gparted.appdata.xml.in b/gparted.appdata.xml.in index 777a4231..843a901b 100644 --- a/gparted.appdata.xml.in +++ b/gparted.appdata.xml.in @@ -18,9 +18,9 @@ data rescue from lost partitions. <_p> - GParted works with many file systems including: btrfs, ext2, ext3, - ext4, fat16, fat32, hfs, hfs+, linux-swap, lvm2 pv, minix, nilfs2, - ntfs, reiserfs, reiser4, udf, ufs, and xfs. + GParted works with many file systems including: btrfs, exfat, ext2, + ext3, ext4, fat16, fat32, hfs, hfs+, linux-swap, lvm2 pv, minix, + nilfs2, ntfs, reiserfs, reiser4, udf, ufs, and xfs. gparted.desktop diff --git a/include/exfat.h b/include/exfat.h index 40132993..aa6f1d62 100644 --- a/include/exfat.h +++ b/include/exfat.h @@ -14,21 +14,30 @@ * along with this program; if not, see . */ - #ifndef GPARTED_EXFAT_H #define GPARTED_EXFAT_H + #include "FileSystem.h" +#include "OperationDetail.h" +#include "Partition.h" + namespace GParted { + class exfat : public FileSystem { public: - FS get_filesystem_support() ; + FS get_filesystem_support(); + bool create(const Partition& new_partition, OperationDetail& operationdetail); + void read_label(Partition& partition); + bool write_label(const Partition& partition, OperationDetail& operationdetail); + bool check_repair(const Partition& partition, OperationDetail& operationdetail); }; + } //GParted #endif /* GPARTED_EXFAT_H */ diff --git a/src/Utils.cc b/src/Utils.cc index 0e4fa389..8c454378 100644 --- a/src/Utils.cc +++ b/src/Utils.cc @@ -261,7 +261,7 @@ int Utils::get_filesystem_label_maxlength(FSType fstype) //All file systems commented out are not supported for labelling // by either the new partition or label partition operations. case FS_BTRFS : return 255 ; - //case FS_EXFAT : return ; + case FS_EXFAT : return 11; case FS_EXT2 : return 16 ; case FS_EXT3 : return 16 ; case FS_EXT4 : return 16 ; @@ -433,6 +433,7 @@ Glib::ustring Utils::get_filesystem_software(FSType fstype) switch (fstype) { case FS_BTRFS : return "btrfs-progs / btrfs-tools" ; + case FS_EXFAT : return "exfatprogs"; case FS_EXT2 : return "e2fsprogs" ; case FS_EXT3 : return "e2fsprogs" ; case FS_EXT4 : return "e2fsprogs v1.41+" ; diff --git a/src/exfat.cc b/src/exfat.cc index e17bbabc..41d0e726 100644 --- a/src/exfat.cc +++ b/src/exfat.cc @@ -16,10 +16,18 @@ #include "exfat.h" #include "FileSystem.h" +#include "OperationDetail.h" +#include "Partition.h" +#include "Utils.h" + +#include +#include + namespace GParted { + FS exfat::get_filesystem_support() { FS fs( FS_EXFAT ); @@ -28,8 +36,61 @@ FS exfat::get_filesystem_support() fs .copy = FS::GPARTED ; fs .move = FS::GPARTED ; fs .online_read = FS::GPARTED ; - - return fs ; + + if (! Glib::find_program_in_path("mkfs.exfat").empty()) + fs.create = FS::EXTERNAL; + + if (! Glib::find_program_in_path("tune.exfat").empty()) + { + fs.read_label = FS::EXTERNAL; + fs.write_label = FS::EXTERNAL; + } + + if (! Glib::find_program_in_path("fsck.exfat").empty()) + fs.check = FS::EXTERNAL; + + return fs; } + +bool exfat::create(const Partition& new_partition, OperationDetail& operationdetail) +{ + return ! execute_command("mkfs.exfat -L " + Glib::shell_quote(new_partition.get_filesystem_label()) + + " " + Glib::shell_quote(new_partition.get_path()), + operationdetail, EXEC_CHECK_STATUS|EXEC_CANCEL_SAFE); +} + + +void exfat::read_label(Partition& partition) +{ + exit_status = Utils::execute_command("tune.exfat -l " + Glib::shell_quote(partition.get_path()), + output, error, true); + if (exit_status != 0) + { + if (! output.empty()) + partition.push_back_message(output); + if (! error.empty()) + partition.push_back_message(error); + return; + } + + partition.set_filesystem_label(Utils::regexp_label(output, "^label: ([^\n]*)")); +} + + +bool exfat::write_label(const Partition& partition, OperationDetail& operationdetail) +{ + return ! execute_command("tune.exfat -L " + Glib::shell_quote(partition.get_filesystem_label()) + + " " + Glib::shell_quote(partition.get_path()), + operationdetail, EXEC_CHECK_STATUS|EXEC_CANCEL_SAFE); +} + + +bool exfat::check_repair(const Partition& partition, OperationDetail& operationdetail) +{ + return ! execute_command("fsck.exfat -v " + Glib::shell_quote(partition.get_path()), + operationdetail, EXEC_CHECK_STATUS|EXEC_CANCEL_SAFE); +} + + } //GParted