Also support reading exFAT usage from exfatprogs <= 1.2.2 (#261)

Exfatprogs 1.2.2 and earlier are included in a number of the latest
distributions.  Therefore support reading exFAT usage from the earlier
dump.exfat style output.

    Distribution                       exfatprogs
    Alpine 3.20                        1.2.2
    Debian 12                          1.2.0
    RHEL / Rocky Linux / AlmaLinux 9   1.2.2
    Ubuntu 24.04 LTS                   1.2.2

On Debian 12, example dump.exfat output:
    # dump.exfat /dev/sdb1 | egrep 'exfatprogs version|Volume Length\(sectors\):|Sector|Free Clusters:'
    exfatprogs version : 1.2.0
    Volume Length(sectors):                 524288
    Sector Size Bits:                       9
    Sector per Cluster bits:                3
    Free Clusters:                          65019

Make this a separate commit so that it can be easily reverted in future
when this is no longer required.  It also results in simpler code as the
old shift bits style figures are converted into new direct multiplier
style figures.  Therefore the final if statement checking all the
figures are set, computing and assigning partition usage remains simple
and unchanged.

Closes #261 - Unable to read the contents of exfat file system with
              exfatprogs >= 1.2.3
This commit is contained in:
Mike Fleetwood 2024-08-03 08:25:51 +01:00
parent 35baa44e2f
commit 344e03439e
1 changed files with 26 additions and 0 deletions

View File

@ -93,6 +93,12 @@ void exfat::set_used_sectors(Partition& partition)
// Bytes per Sector: 512
// Sectors per Cluster: 8
// Free Clusters: 65024
// Example output from exfatprogs <= 1.2.2 (lines of interest only):
// # dump.exfat /dev/sdb1
// Volume Length(sectors): 524288
// Sector Size Bits: 9
// Sectors per Cluster Bits: 3
// Free Clusters: 65019
//
// "exFAT file system specification"
// https://docs.microsoft.com/en-us/windows/win32/fileio/exfat-specification
@ -111,12 +117,32 @@ void exfat::set_used_sectors(Partition& partition)
index = output.find("Bytes per Sector:");
if (index < output.length())
sscanf(output.substr(index).c_str(), "Bytes per Sector: %lld", &bytes_per_sector);
if (bytes_per_sector == -1)
{
// FS sector size = 2^(bytes_per_sector_shift)
long long bytes_per_sector_shift = -1;
index = output.find("Sector Size Bits:");
if (index < output.length())
sscanf(output.substr(index).c_str(), "Sector Size Bits: %lld", &bytes_per_sector_shift);
if (bytes_per_sector_shift > -1)
bytes_per_sector = 1 << bytes_per_sector_shift;
}
// Cluster size in FS sectors
long long sectors_per_cluster = -1;
index = output.find("Sectors per Cluster:");
if (index < output.length())
sscanf(output.substr(index).c_str(), "Sectors per Cluster: %lld", &sectors_per_cluster);
if (sectors_per_cluster == -1)
{
// Cluster size in FS sectors = 2^(sectors_per_cluster_shift)
long long sectors_per_cluster_shift = -1;
index = output.find("Sector per Cluster bits:");
if (index < output.length())
sscanf(output.substr(index).c_str(), "Sector per Cluster bits: %lld", &sectors_per_cluster_shift);
if (sectors_per_cluster_shift > -1)
sectors_per_cluster = 1 << sectors_per_cluster_shift;
}
// Free clusters
long long free_clusters = -1;