diff --git a/FATX/Analyzers/MetadataAnalyzer.cs b/FATX/Analyzers/MetadataAnalyzer.cs index c8c6bfa..854613f 100644 --- a/FATX/Analyzers/MetadataAnalyzer.cs +++ b/FATX/Analyzers/MetadataAnalyzer.cs @@ -58,7 +58,20 @@ private void RecoverMetadata(CancellationToken cancellationToken, IProgress var maxClusters = _length / _interval; for (uint cluster = 1; cluster < maxClusters; cluster++) { - var data = _volume.ReadCluster(cluster); + byte[] data; + + try + { + data = _volume.ReadCluster(cluster); + } + catch (IOException exception) + { + // Failed to read data + Console.WriteLine(exception.Message); + Console.WriteLine($"Failed to read cluster {cluster}, skipping..."); + continue; + } + var clusterOffset = (cluster - 1) * _interval; for (int i = 0; i < 256; i++) { diff --git a/FATX/FileSystem/Volume.cs b/FATX/FileSystem/Volume.cs index 0a6fa1c..794c003 100644 --- a/FATX/FileSystem/Volume.cs +++ b/FATX/FileSystem/Volume.cs @@ -286,7 +286,20 @@ private List ReadDirectoryStream(uint cluster) { List stream = new List(); - byte[] data = ReadCluster(cluster); + byte[] data; + + try + { + data = ReadCluster(cluster); + } + catch (IOException exception) + { + // Failed to read data, return an empty list + Console.WriteLine(exception.Message); + Console.WriteLine($"Due to exception, returning empty directory stream for cluster {cluster}"); + return stream; + } + long clusterOffset = ClusterToPhysicalOffset(cluster); for (int i = 0; i < 256; i++) @@ -364,6 +377,7 @@ public void SeekToCluster(uint cluster) /// Reads a cluster and returns the data. /// /// + /// May be thrown on read errors. /// public byte[] ReadCluster(uint cluster) { diff --git a/FATXTools/Controls/FileExplorer.cs b/FATXTools/Controls/FileExplorer.cs index e50ec7d..d9e59d9 100644 --- a/FATXTools/Controls/FileExplorer.cs +++ b/FATXTools/Controls/FileExplorer.cs @@ -463,7 +463,20 @@ private void WriteFile(string path, DirectoryEntry dirent, List chainMap) foreach (uint cluster in chainMap) { - byte[] clusterData = this.volume.ReadCluster(cluster); + byte[] clusterData; + + try + { + clusterData = this.volume.ReadCluster(cluster); + } + catch (IOException exception) + { + // Failed to read cluster, write null bytes instead. + var position = outFile.Position; + Console.WriteLine(exception.Message); + Console.WriteLine($"Due to exception, writing null cluster at {position} to file: {path}"); + clusterData = new byte[volume.BytesPerCluster]; + } var writeSize = Math.Min(bytesLeft, this.volume.BytesPerCluster); outFile.Write(clusterData, 0, (int)writeSize); diff --git a/FATXTools/Controls/RecoveryResults.cs b/FATXTools/Controls/RecoveryResults.cs index b0f3103..edecbc2 100644 --- a/FATXTools/Controls/RecoveryResults.cs +++ b/FATXTools/Controls/RecoveryResults.cs @@ -586,7 +586,20 @@ private void WriteFile(string path, DatabaseFile databaseFile) foreach (uint cluster in databaseFile.ClusterChain) { - byte[] clusterData = this.volume.ReadCluster(cluster); + byte[] clusterData; + + try + { + clusterData = this.volume.ReadCluster(cluster); + } + catch (IOException exception) + { + // Failed to read cluster, write null bytes instead. + var position = outFile.Position; + Console.WriteLine(exception.Message); + Console.WriteLine($"Due to exception, writing null cluster at {position} to file: {path}"); + clusterData = new byte[volume.BytesPerCluster]; + } var writeSize = Math.Min(bytesLeft, this.volume.BytesPerCluster); outFile.Write(clusterData, 0, (int)writeSize);