Read exFAT file system usage only from exfatprogs >= 1.2.3 (#261)

exFAT file system usage is no longer readable when exfatprogs 1.2.3,
released 2024-05-23 [1], and later is installed.  This is because the
output from dump.exfat changed as a result of commit [2].

On Fedora 39 with exfatprogs 1.2.3 installed and exfatprogs 1.2.2
compiled locally from git; old dump.exfat output:
    # ~fedora/programming/c/exfatprogs/dump/dump.exfat /dev/sdb1 | egrep 'exfatprogs version|Volume Length\(sectors\):|Sector|Free Clusters:'
    exfatprogs version : 1.2.2
    Volume Length(sectors):                 524288
>>  Sector Size Bits:                       9
>>  Sector per Cluster bits:                3
    Free Clusters:                          65024

New dump.exfat output:
    # dump.exfat /dev/sdb1 | egrep 'exfatprogs version|Volume Length\(sectors\):|Sector|Free Clusters:'
    exfatprogs version : 1.2.3
    Volume Length(sectors):                 524288
>>  Bytes per Sector:                       512
>>  Sectors per Cluster:                    8
    Free Clusters:                          65024

Change the code to read exFAT usage only from dump.exfat 1.2.3 style
output.  Don't parse older style output for now as that makes the code
simpler.

[1] exfatprogs-1.2.3 version released
    https://github.com/exfatprogs/exfatprogs/releases/tag/1.2.3
[2] dump: Sector and Cluster units
    41863cb0f5

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-02 20:57:11 +01:00
parent fd39aa5d7e
commit 35baa44e2f
1 changed files with 16 additions and 18 deletions

View File

@ -87,12 +87,12 @@ void exfat::set_used_sectors(Partition& partition)
return; return;
} }
// Example output (lines of interest only): // Example output from exfatprogs >= 1.2.3 (lines of interest only):
// $ dump.exfat /dev/sdb1 // # dump.exfat /dev/sdb1
// Volume Length(sectors): 524288 // Volume Length(sectors): 524288
// Sector Size Bits: 9 // Bytes per Sector: 512
// Sector per Cluster bits: 3 // Sectors per Cluster: 8
// Free Clusters: 23585 // Free Clusters: 65024
// //
// "exFAT file system specification" // "exFAT file system specification"
// https://docs.microsoft.com/en-us/windows/win32/fileio/exfat-specification // https://docs.microsoft.com/en-us/windows/win32/fileio/exfat-specification
@ -106,17 +106,17 @@ void exfat::set_used_sectors(Partition& partition)
if (index < output.length()) if (index < output.length())
sscanf(output.substr(index).c_str(), "Volume Length(sectors): %lld", &volume_length); sscanf(output.substr(index).c_str(), "Volume Length(sectors): %lld", &volume_length);
// FS sector size = 2^(bytes_per_sector_shift) // FS sector size
long long bytes_per_sector_shift = -1; long long bytes_per_sector = -1;
index = output.find("Sector Size Bits:"); index = output.find("Bytes per Sector:");
if (index < output.length()) if (index < output.length())
sscanf(output.substr(index).c_str(), "Sector Size Bits: %lld", &bytes_per_sector_shift); sscanf(output.substr(index).c_str(), "Bytes per Sector: %lld", &bytes_per_sector);
// Cluster size = sector_size * 2^(sectors_per_cluster_shift) // Cluster size in FS sectors
long long sectors_per_cluster_shift = -1; long long sectors_per_cluster = -1;
index = output.find("Sector per Cluster bits:"); index = output.find("Sectors per Cluster:");
if (index < output.length()) if (index < output.length())
sscanf(output.substr(index).c_str(), "Sector per Cluster bits: %lld", &sectors_per_cluster_shift); sscanf(output.substr(index).c_str(), "Sectors per Cluster: %lld", &sectors_per_cluster);
// Free clusters // Free clusters
long long free_clusters = -1; long long free_clusters = -1;
@ -124,13 +124,11 @@ void exfat::set_used_sectors(Partition& partition)
if (index < output.length()) if (index < output.length())
sscanf(output.substr(index).c_str(), "Free Clusters: %lld", &free_clusters); sscanf(output.substr(index).c_str(), "Free Clusters: %lld", &free_clusters);
if ( volume_length > -1 && bytes_per_sector_shift > -1 && if (volume_length > -1 && bytes_per_sector > -1 && sectors_per_cluster > -1 && free_clusters > -1)
sectors_per_cluster_shift > -1 && free_clusters > -1 )
{ {
Byte_Value sector_size = 1 << bytes_per_sector_shift; Byte_Value cluster_size = bytes_per_sector * sectors_per_cluster;
Byte_Value cluster_size = sector_size * (1 << sectors_per_cluster_shift); Sector fs_size = volume_length * bytes_per_sector / partition.sector_size;
Sector fs_free = free_clusters * cluster_size / partition.sector_size; Sector fs_free = free_clusters * cluster_size / partition.sector_size;
Sector fs_size = volume_length * sector_size / partition.sector_size;
partition.set_sector_usage(fs_size, fs_free); partition.set_sector_usage(fs_size, fs_free);
partition.fs_block_size = cluster_size; partition.fs_block_size = cluster_size;
} }