diff --git a/Aaru.CommonTypes b/Aaru.CommonTypes index e4724dbe0..0fc3e1ef9 160000 --- a/Aaru.CommonTypes +++ b/Aaru.CommonTypes @@ -1 +1 @@ -Subproject commit e4724dbe0be59095299b4684437eb0189b77d4c2 +Subproject commit 0fc3e1ef94f293ceb0f42500b1d4f2aa12293963 diff --git a/Aaru.Core/Entropy.cs b/Aaru.Core/Entropy.cs index 635dd39e2..45a1f841f 100644 --- a/Aaru.Core/Entropy.cs +++ b/Aaru.Core/Entropy.cs @@ -118,7 +118,14 @@ namespace Aaru.Core UpdateProgress2Event?.Invoke($"Entropying sector {i + 1} of track {currentTrack.Sequence}", (long)(i + 1), (long)currentTrack.EndSector); - byte[] sector = opticalMediaImage.ReadSector(i, currentTrack.Sequence); + ErrorNumber errno = opticalMediaImage.ReadSector(i, currentTrack.Sequence, out byte[] sector); + + if(errno != ErrorNumber.NoError) + { + AaruConsole.ErrorWriteLine($"Error {errno} while reading sector {i}, continuing..."); + + continue; + } if(duplicatedSectors) { diff --git a/Aaru.Gui/ViewModels/Windows/ImageChecksumViewModel.cs b/Aaru.Gui/ViewModels/Windows/ImageChecksumViewModel.cs index 122ca4540..b5fa0b3d7 100644 --- a/Aaru.Gui/ViewModels/Windows/ImageChecksumViewModel.cs +++ b/Aaru.Gui/ViewModels/Windows/ImageChecksumViewModel.cs @@ -515,8 +515,16 @@ namespace Aaru.Gui.ViewModels.Windows if(sectors - doneSectors >= SECTORS_TO_READ) { - sector = opticalMediaImage.ReadSectors(doneSectors, SECTORS_TO_READ, - currentTrack.Sequence); + errno = opticalMediaImage.ReadSectors(doneSectors, SECTORS_TO_READ, + currentTrack.Sequence, out sector); + + if(errno != ErrorNumber.NoError) + { + AaruConsole.ErrorWriteLine($"Error {errno} reading sector {doneSectors}"); + _cancel = true; + + continue; + } ulong doneSectorsToInvoke = doneSectors; @@ -532,8 +540,16 @@ namespace Aaru.Gui.ViewModels.Windows } else { - sector = opticalMediaImage.ReadSectors(doneSectors, (uint)(sectors - doneSectors), - currentTrack.Sequence); + errno = opticalMediaImage.ReadSectors(doneSectors, (uint)(sectors - doneSectors), + currentTrack.Sequence, out sector); + + if(errno != ErrorNumber.NoError) + { + AaruConsole.ErrorWriteLine($"Error {errno} reading sector {doneSectors}"); + _cancel = true; + + continue; + } ulong doneSectorsToInvoke = doneSectors; diff --git a/Aaru.Images/AaruFormat/Read.cs b/Aaru.Images/AaruFormat/Read.cs index 86ca79007..fa3759456 100644 --- a/Aaru.Images/AaruFormat/Read.cs +++ b/Aaru.Images/AaruFormat/Read.cs @@ -1607,19 +1607,17 @@ namespace Aaru.DiscImages ReadSectorsTag(sectorAddress, 1, tag, out buffer); /// - public byte[] ReadSector(ulong sectorAddress, uint track) + public ErrorNumber ReadSector(ulong sectorAddress, uint track, out byte[] buffer) { + buffer = null; + if(_imageInfo.XmlMediaType != XmlMediaType.OpticalDisc) - throw new FeatureNotPresentImageException("Feature not present in image"); + return ErrorNumber.NotSupported; Track trk = Tracks.FirstOrDefault(t => t.Sequence == track); - if(trk?.Sequence != track) - throw new ArgumentOutOfRangeException(nameof(track), "Track does not exist in disc image"); - - ReadSector(trk.StartSector + sectorAddress, out byte[] sector); - - return sector; + return trk?.Sequence != track ? ErrorNumber.SectorNotFound + : ReadSector(trk.StartSector + sectorAddress, out buffer); } /// @@ -1949,23 +1947,20 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSectors(ulong sectorAddress, uint length, uint track) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, uint track, out byte[] buffer) { + buffer = null; + if(_imageInfo.XmlMediaType != XmlMediaType.OpticalDisc) - throw new FeatureNotPresentImageException("Feature not present in image"); + return ErrorNumber.NotSupported; Track trk = Tracks.FirstOrDefault(t => t.Sequence == track); if(trk?.Sequence != track) - throw new ArgumentOutOfRangeException(nameof(track), "Track does not exist in disc image"); + return ErrorNumber.SectorNotFound; - if(trk.StartSector + sectorAddress + length > trk.EndSector + 1) - throw new ArgumentOutOfRangeException(nameof(length), - $"Requested more sectors ({length + sectorAddress}) than present in track ({trk.EndSector - trk.StartSector + 1}), won't cross tracks"); - - ReadSectors(trk.StartSector + sectorAddress, length, out byte[] buffer); - - return buffer; + return trk.StartSector + sectorAddress + length > trk.EndSector + 1 ? ErrorNumber.OutOfRange + : ReadSectors(trk.StartSector + sectorAddress, length, out buffer); } /// diff --git a/Aaru.Images/Alcohol120/Read.cs b/Aaru.Images/Alcohol120/Read.cs index 963c407f4..16f18aea3 100644 --- a/Aaru.Images/Alcohol120/Read.cs +++ b/Aaru.Images/Alcohol120/Read.cs @@ -789,7 +789,8 @@ namespace Aaru.DiscImages ReadSectorsTag(sectorAddress, 1, tag, out buffer); /// - public byte[] ReadSector(ulong sectorAddress, uint track) => ReadSectors(sectorAddress, 1, track); + public ErrorNumber ReadSector(ulong sectorAddress, uint track, out byte[] buffer) => + ReadSectors(sectorAddress, 1, track, out buffer); /// public byte[] ReadSectorTag(ulong sectorAddress, uint track, SectorTagType tag) => @@ -811,9 +812,7 @@ namespace Aaru.DiscImages if(sectorAddress - kvp.Value >= extra.sectors + extra.pregap) continue; - buffer = ReadSectors(sectorAddress - kvp.Value, length, kvp.Key); - - return ErrorNumber.NoError; + return ReadSectors(sectorAddress - kvp.Value, length, kvp.Key, out buffer); } return ErrorNumber.SectorNotFound; @@ -844,15 +843,16 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSectors(ulong sectorAddress, uint length, uint track) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, uint track, out byte[] buffer) { + buffer = null; + if(!_alcTracks.TryGetValue((int)track, out Track alcTrack) || !_alcTrackExtras.TryGetValue((int)track, out TrackExtra alcExtra)) - throw new ArgumentOutOfRangeException(nameof(track), "Track does not exist in disc image"); + return ErrorNumber.OutOfRange; if(length + sectorAddress > alcExtra.sectors + alcExtra.pregap) - throw new ArgumentOutOfRangeException(nameof(length), - $"Requested more sectors ({length + sectorAddress}) than present in track ({alcExtra.sectors + alcExtra.pregap}), won't cross tracks"); + return ErrorNumber.OutOfRange; uint sectorOffset; uint sectorSize; @@ -904,7 +904,7 @@ namespace Aaru.DiscImages break; } - default: throw new FeatureSupportedButNotImplementedImageException("Unsupported track type"); + default: return ErrorNumber.NotSupported; } switch(alcTrack.subMode) @@ -917,16 +917,16 @@ namespace Aaru.DiscImages sectorSkip += 96; break; - default: throw new FeatureSupportedButNotImplementedImageException("Unsupported subchannel type"); + default: return ErrorNumber.NotSupported; } - byte[] buffer = new byte[sectorSize * length]; + buffer = new byte[sectorSize * length]; if(alcTrack.point == 1 && alcExtra.pregap > 150) { if(sectorAddress + 150 < alcExtra.pregap) - return buffer; + return ErrorNumber.NoError; sectorAddress -= alcExtra.pregap - 150; } @@ -971,7 +971,7 @@ namespace Aaru.DiscImages Array.Copy(sector, 0, buffer, i * sectorSize, sectorSize); } - return buffer; + return ErrorNumber.NoError; } /// diff --git a/Aaru.Images/BlindWrite4/Read.cs b/Aaru.Images/BlindWrite4/Read.cs index 664c1521a..89290c981 100644 --- a/Aaru.Images/BlindWrite4/Read.cs +++ b/Aaru.Images/BlindWrite4/Read.cs @@ -840,7 +840,8 @@ namespace Aaru.DiscImages ReadSectorsTag(sectorAddress, 1, tag, out buffer); /// - public byte[] ReadSector(ulong sectorAddress, uint track) => ReadSectors(sectorAddress, 1, track); + public ErrorNumber ReadSector(ulong sectorAddress, uint track, out byte[] buffer) => + ReadSectors(sectorAddress, 1, track, out buffer); /// public byte[] ReadSectorTag(ulong sectorAddress, uint track, SectorTagType tag) => @@ -855,11 +856,7 @@ namespace Aaru.DiscImages from track in Tracks where track.Sequence == kvp.Key where sectorAddress - kvp.Value < track.EndSector - track.StartSector + 1 select kvp) - { - buffer = ReadSectors(sectorAddress - kvp.Value, length, kvp.Key); - - return ErrorNumber.NoError; - } + return ReadSectors(sectorAddress - kvp.Value, length, kvp.Key, out buffer); return ErrorNumber.SectorNotFound; } @@ -883,26 +880,16 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSectors(ulong sectorAddress, uint length, uint track) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, uint track, out byte[] buffer) { - var aaruTrack = new Track - { - Sequence = 0 - }; - - foreach(Track bwTrack in Tracks.Where(bwTrack => bwTrack.Sequence == track)) - { - aaruTrack = bwTrack; - - break; - } + buffer = null; + Track? aaruTrack = Tracks.FirstOrDefault(bwTrack => bwTrack.Sequence == track); if(aaruTrack is null) - throw new ArgumentOutOfRangeException(nameof(track), "Track does not exist in disc image"); + return ErrorNumber.SectorNotFound; if(length + sectorAddress > aaruTrack.EndSector - aaruTrack.StartSector + 1) - throw new ArgumentOutOfRangeException(nameof(length), - $"Requested more sectors ({length + sectorAddress}) than present in track ({aaruTrack.EndSector - aaruTrack.StartSector + 1}), won't cross tracks"); + return ErrorNumber.OutOfRange; uint sectorOffset; uint sectorSize; @@ -944,10 +931,10 @@ namespace Aaru.DiscImages break; } - default: throw new FeatureSupportedButNotImplementedImageException("Unsupported track type"); + default: return ErrorNumber.NotSupported; } - byte[] buffer = new byte[sectorSize * length]; + buffer = new byte[sectorSize * length]; _imageStream = aaruTrack.Filter.GetDataForkStream(); var br = new BinaryReader(_imageStream); @@ -985,7 +972,7 @@ namespace Aaru.DiscImages Array.Copy(sector, 0, buffer, i * sectorSize, sectorSize); } - return buffer; + return ErrorNumber.NoError; } /// diff --git a/Aaru.Images/BlindWrite5/Read.cs b/Aaru.Images/BlindWrite5/Read.cs index 0de9f77fa..2e66a3fcf 100644 --- a/Aaru.Images/BlindWrite5/Read.cs +++ b/Aaru.Images/BlindWrite5/Read.cs @@ -1441,7 +1441,8 @@ namespace Aaru.DiscImages ReadSectorsTag(sectorAddress, 1, tag, out buffer); /// - public byte[] ReadSector(ulong sectorAddress, uint track) => ReadSectors(sectorAddress, 1, track); + public ErrorNumber ReadSector(ulong sectorAddress, uint track, out byte[] buffer) => + ReadSectors(sectorAddress, 1, track, out buffer); /// public byte[] ReadSectorTag(ulong sectorAddress, uint track, SectorTagType tag) => @@ -1456,11 +1457,7 @@ namespace Aaru.DiscImages from track in Tracks where track.Sequence == kvp.Key where sectorAddress - kvp.Value < track.EndSector - track.StartSector + 1 select kvp) - { - buffer = ReadSectors(sectorAddress - kvp.Value, length, kvp.Key); - - return ErrorNumber.NoError; - } + return ReadSectors(sectorAddress - kvp.Value, length, kvp.Key, out buffer); return ErrorNumber.SectorNotFound; } @@ -1484,27 +1481,18 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSectors(ulong sectorAddress, uint length, uint track) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, uint track, out byte[] buffer) { + buffer = null; + // TODO: Cross data files - var aaruTrack = new Track - { - Sequence = 0 - }; - - foreach(Track bwTrack in Tracks.Where(bwTrack => bwTrack.Sequence == track)) - { - aaruTrack = bwTrack; - - break; - } + Track? aaruTrack = Tracks.FirstOrDefault(bwTrack => bwTrack.Sequence == track); if(aaruTrack is null) - throw new ArgumentOutOfRangeException(nameof(track), "Track does not exist in disc image"); + return ErrorNumber.SectorNotFound; if(length + sectorAddress > aaruTrack.EndSector - aaruTrack.StartSector + 1) - throw new ArgumentOutOfRangeException(nameof(length), - $"Requested more sectors ({length + sectorAddress}) than present in track ({aaruTrack.EndSector - aaruTrack.StartSector + 1}), won't cross tracks"); + return ErrorNumber.OutOfRange; DataFileCharacteristics chars = (from characteristics in _filePaths let firstSector = characteristics.StartLba let lastSector = @@ -1515,7 +1503,7 @@ namespace Aaru.DiscImages if(string.IsNullOrEmpty(chars.FilePath) || chars.FileFilter == null) - throw new ArgumentOutOfRangeException(nameof(chars.FileFilter), "Track does not exist in disc image"); + return ErrorNumber.SectorNotFound; uint sectorOffset; uint sectorSize; @@ -1559,7 +1547,7 @@ namespace Aaru.DiscImages break; } - default: throw new FeatureSupportedButNotImplementedImageException("Unsupported track type"); + default: return ErrorNumber.NotSupported; } switch(chars.Subchannel) @@ -1576,10 +1564,10 @@ namespace Aaru.DiscImages sectorSkip += 96; break; - default: throw new FeatureSupportedButNotImplementedImageException("Unsupported subchannel type"); + default: return ErrorNumber.NotSupported; } - byte[] buffer = new byte[sectorSize * length]; + buffer = new byte[sectorSize * length]; _imageStream = chars.FileFilter.GetDataForkStream(); var br = new BinaryReader(_imageStream); @@ -1616,7 +1604,7 @@ namespace Aaru.DiscImages Array.Copy(sector, 0, buffer, i * sectorSize, sectorSize); } - return buffer; + return ErrorNumber.NoError; } /// diff --git a/Aaru.Images/CDRDAO/Read.cs b/Aaru.Images/CDRDAO/Read.cs index 0d78e2fb6..ff3f01788 100644 --- a/Aaru.Images/CDRDAO/Read.cs +++ b/Aaru.Images/CDRDAO/Read.cs @@ -921,7 +921,8 @@ namespace Aaru.DiscImages ReadSectorsTag(sectorAddress, 1, tag, out buffer); /// - public byte[] ReadSector(ulong sectorAddress, uint track) => ReadSectors(sectorAddress, 1, track); + public ErrorNumber ReadSector(ulong sectorAddress, uint track, out byte[] buffer) => + ReadSectors(sectorAddress, 1, track, out buffer); /// public byte[] ReadSectorTag(ulong sectorAddress, uint track, SectorTagType tag) => @@ -936,11 +937,7 @@ namespace Aaru.DiscImages from cdrdaoTrack in _discimage.Tracks where cdrdaoTrack.Sequence == kvp.Key where sectorAddress - kvp.Value < cdrdaoTrack.Sectors select kvp) - { - buffer = ReadSectors(sectorAddress - kvp.Value, length, kvp.Key); - - return ErrorNumber.NoError; - } + return ReadSectors(sectorAddress - kvp.Value, length, kvp.Key, out buffer); return ErrorNumber.SectorNotFound; } @@ -964,8 +961,10 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSectors(ulong sectorAddress, uint length, uint track) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, uint track, out byte[] buffer) { + buffer = null; + var aaruTrack = new CdrdaoTrack { Sequence = 0 @@ -979,11 +978,10 @@ namespace Aaru.DiscImages } if(aaruTrack.Sequence == 0) - throw new ArgumentOutOfRangeException(nameof(track), "Track does not exist in disc image"); + return ErrorNumber.SectorNotFound; if(length > aaruTrack.Sectors) - throw new ArgumentOutOfRangeException(nameof(length), - "Requested more sectors than present in track, won't cross tracks"); + return ErrorNumber.OutOfRange; uint sectorOffset; uint sectorSize; @@ -1044,13 +1042,13 @@ namespace Aaru.DiscImages break; } - default: throw new FeatureSupportedButNotImplementedImageException("Unsupported track type"); + default: return ErrorNumber.NotSupported; } if(aaruTrack.Subchannel) sectorSkip += 96; - byte[] buffer = new byte[sectorSize * length]; + buffer = new byte[sectorSize * length]; _imageStream = aaruTrack.Trackfile.Datafilter.GetDataForkStream(); var br = new BinaryReader(_imageStream); @@ -1089,7 +1087,7 @@ namespace Aaru.DiscImages // cdrdao audio tracks are endian swapped corresponding to Aaru if(aaruTrack.Tracktype != CDRDAO_TRACK_TYPE_AUDIO) - return buffer; + return ErrorNumber.NoError; byte[] swapped = new byte[buffer.Length]; @@ -1099,7 +1097,9 @@ namespace Aaru.DiscImages swapped[i + 1] = buffer[i]; } - return swapped; + buffer = swapped; + + return ErrorNumber.NoError; } /// diff --git a/Aaru.Images/CDRWin/Read.cs b/Aaru.Images/CDRWin/Read.cs index 9f6b15118..1d96dc104 100644 --- a/Aaru.Images/CDRWin/Read.cs +++ b/Aaru.Images/CDRWin/Read.cs @@ -1588,7 +1588,8 @@ namespace Aaru.DiscImages ReadSectorsTag(sectorAddress, 1, tag, out buffer); /// - public byte[] ReadSector(ulong sectorAddress, uint track) => ReadSectors(sectorAddress, 1, track); + public ErrorNumber ReadSector(ulong sectorAddress, uint track, out byte[] buffer) => + ReadSectors(sectorAddress, 1, track, out buffer); /// public byte[] ReadSectorTag(ulong sectorAddress, uint track, SectorTagType tag) => @@ -1603,11 +1604,7 @@ namespace Aaru.DiscImages from cdrwinTrack in _discImage.Tracks where cdrwinTrack.Sequence == kvp.Key where sectorAddress - kvp.Value < cdrwinTrack.Sectors select kvp) - { - buffer = ReadSectors(sectorAddress - kvp.Value, length, kvp.Key); - - return ErrorNumber.NoError; - } + return ReadSectors(sectorAddress - kvp.Value, length, kvp.Key, out buffer); return ErrorNumber.SectorNotFound; } @@ -1639,26 +1636,16 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSectors(ulong sectorAddress, uint length, uint track) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, uint track, out byte[] buffer) { - var aaruTrack = new CdrWinTrack - { - Sequence = 0 - }; + buffer = null; + CdrWinTrack? aaruTrack = _discImage.Tracks.FirstOrDefault(cdrwinTrack => cdrwinTrack.Sequence == track); - foreach(CdrWinTrack cdrwinTrack in _discImage.Tracks.Where(cdrwinTrack => cdrwinTrack.Sequence == track)) - { - aaruTrack = cdrwinTrack; - - break; - } - - if(aaruTrack.Sequence == 0) - throw new ArgumentOutOfRangeException(nameof(track), "Track does not exist in disc image"); + if(aaruTrack is null) + return ErrorNumber.SectorNotFound; if(length > aaruTrack.Sectors) - throw new ArgumentOutOfRangeException(nameof(length), - "Requested more sectors than present in track, won't cross tracks"); + return ErrorNumber.OutOfRange; uint sectorOffset; uint sectorSize; @@ -1728,10 +1715,10 @@ namespace Aaru.DiscImages break; } - default: throw new FeatureSupportedButNotImplementedImageException("Unsupported track type"); + default: return ErrorNumber.NotSupported; } - byte[] buffer = new byte[sectorSize * length]; + buffer = new byte[sectorSize * length]; // If it's the lost pregap if(track == 1 && @@ -1741,14 +1728,19 @@ namespace Aaru.DiscImages { // If we need to mix lost with present data if(sectorAddress + length <= _lostPregap) - return buffer; + return ErrorNumber.NoError; ulong pregapPos = _lostPregap - sectorAddress; - byte[] presentData = ReadSectors(_lostPregap, (uint)(length - pregapPos), track); + ErrorNumber errno = + ReadSectors(_lostPregap, (uint)(length - pregapPos), track, out byte[] presentData); + + if(errno != ErrorNumber.NoError) + return errno; + Array.Copy(presentData, 0, buffer, (long)(pregapPos * sectorSize), presentData.Length); - return buffer; + return ErrorNumber.NoError; } sectorAddress -= _lostPregap; @@ -1789,7 +1781,7 @@ namespace Aaru.DiscImages Array.Copy(sector, 0, buffer, i * sectorSize, sectorSize); } - return buffer; + return ErrorNumber.NoError; } /// @@ -2009,7 +2001,12 @@ namespace Aaru.DiscImages ulong pregapPos = _lostPregap - sectorAddress; - byte[] presentData = ReadSectors(_lostPregap, (uint)(length - pregapPos), track); + ErrorNumber errno = + ReadSectors(_lostPregap, (uint)(length - pregapPos), track, out byte[] presentData); + + if(errno != ErrorNumber.NoError) + return null; + Array.Copy(presentData, 0, buffer, (long)(pregapPos * sectorSize), presentData.Length); return buffer; @@ -2069,7 +2066,11 @@ namespace Aaru.DiscImages public byte[] ReadSectorsLong(ulong sectorAddress, uint length, uint track) { if(!_isCd) - return ReadSectors(sectorAddress, length, track); + { + ErrorNumber errno = ReadSectors(sectorAddress, length, track, out byte[] nonCdBuffer); + + return errno != ErrorNumber.NoError ? null : nonCdBuffer; + } var aaruTrack = new CdrWinTrack { @@ -2158,7 +2159,12 @@ namespace Aaru.DiscImages ulong pregapPos = _lostPregap - sectorAddress; - byte[] presentData = ReadSectors(_lostPregap, (uint)(length - pregapPos), track); + ErrorNumber errno = + ReadSectors(_lostPregap, (uint)(length - pregapPos), track, out byte[] presentData); + + if(errno != ErrorNumber.NoError) + return null; + Array.Copy(presentData, 0, buffer, (long)(pregapPos * sectorSize), presentData.Length); return buffer; diff --git a/Aaru.Images/CHD/Read.cs b/Aaru.Images/CHD/Read.cs index fd55b40f8..5e2d11f0d 100644 --- a/Aaru.Images/CHD/Read.cs +++ b/Aaru.Images/CHD/Read.cs @@ -1939,14 +1939,11 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSector(ulong sectorAddress, uint track) + public ErrorNumber ReadSector(ulong sectorAddress, uint track, out byte[] buffer) { - if(_isHdd) - throw new FeaturedNotSupportedByDiscImageException("Cannot access optical tracks on a hard disk image"); + buffer = null; - ErrorNumber errno = ReadSector(GetAbsoluteSector(sectorAddress, track), out byte[] buffer); - - return errno == ErrorNumber.NoError ? buffer : null; + return _isHdd ? ErrorNumber.NotSupported : ReadSector(GetAbsoluteSector(sectorAddress, track), out buffer); } /// @@ -1961,14 +1958,12 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSectors(ulong sectorAddress, uint length, uint track) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, uint track, out byte[] buffer) { - if(_isHdd) - throw new FeaturedNotSupportedByDiscImageException("Cannot access optical tracks on a hard disk image"); + buffer = null; - ErrorNumber errno = ReadSectors(GetAbsoluteSector(sectorAddress, track), length, out byte[] buffer); - - return errno == ErrorNumber.NoError ? buffer : null; + return _isHdd ? ErrorNumber.NotSupported + : ReadSectors(GetAbsoluteSector(sectorAddress, track), length, out buffer); } /// diff --git a/Aaru.Images/CloneCD/Read.cs b/Aaru.Images/CloneCD/Read.cs index 0b403e7f5..61b0899f2 100644 --- a/Aaru.Images/CloneCD/Read.cs +++ b/Aaru.Images/CloneCD/Read.cs @@ -937,7 +937,8 @@ namespace Aaru.DiscImages ReadSectorsTag(sectorAddress, 1, tag, out buffer); /// - public byte[] ReadSector(ulong sectorAddress, uint track) => ReadSectors(sectorAddress, 1, track); + public ErrorNumber ReadSector(ulong sectorAddress, uint track, out byte[] buffer) => + ReadSectors(sectorAddress, 1, track, out buffer); /// public byte[] ReadSectorTag(ulong sectorAddress, uint track, SectorTagType tag) => @@ -952,11 +953,7 @@ namespace Aaru.DiscImages from track in Tracks where track.Sequence == kvp.Key where sectorAddress - kvp.Value < track.EndSector - track.StartSector + 1 select kvp) - { - buffer = ReadSectors(sectorAddress - kvp.Value, length, kvp.Key); - - return ErrorNumber.NoError; - } + return ReadSectors(sectorAddress - kvp.Value, length, kvp.Key, out buffer); return ErrorNumber.SectorNotFound; } @@ -985,29 +982,16 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSectors(ulong sectorAddress, uint length, uint track) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, uint track, out byte[] buffer) { - var aaruTrack = new Track - { - Sequence = 0 - }; - - foreach(Track linqTrack in Tracks.Where(linqTrack => linqTrack.Sequence == track)) - { - aaruTrack = linqTrack; - - break; - } + buffer = null; + Track? aaruTrack = Tracks.FirstOrDefault(linqTrack => linqTrack.Sequence == track); if(aaruTrack is null) - throw new ArgumentOutOfRangeException(nameof(track), "Track does not exist in disc image"); + return ErrorNumber.SectorNotFound; if(length + sectorAddress - 1 > aaruTrack.EndSector) - throw new ArgumentOutOfRangeException(nameof(length), - string. - Format("Requested more sectors ({0} {2}) than present in track ({1}), won't cross tracks", - length + sectorAddress, aaruTrack.EndSector, - sectorAddress)); + return ErrorNumber.OutOfRange; uint sectorOffset; uint sectorSize; @@ -1043,10 +1027,10 @@ namespace Aaru.DiscImages break; } - default: throw new FeatureSupportedButNotImplementedImageException("Unsupported track type"); + default: return ErrorNumber.NotSupported; } - byte[] buffer = new byte[sectorSize * length]; + buffer = new byte[sectorSize * length]; _dataStream.Seek((long)(aaruTrack.FileOffset + (sectorAddress * 2352)), SeekOrigin.Begin); @@ -1079,7 +1063,7 @@ namespace Aaru.DiscImages Array.Copy(sector, 0, buffer, i * sectorSize, sectorSize); } - return buffer; + return ErrorNumber.NoError; } /// diff --git a/Aaru.Images/DiscJuggler/Read.cs b/Aaru.Images/DiscJuggler/Read.cs index d22bfcac7..6e37d3548 100644 --- a/Aaru.Images/DiscJuggler/Read.cs +++ b/Aaru.Images/DiscJuggler/Read.cs @@ -816,7 +816,8 @@ namespace Aaru.DiscImages ReadSectorsTag(sectorAddress, 1, tag, out buffer); /// - public byte[] ReadSector(ulong sectorAddress, uint track) => ReadSectors(sectorAddress, 1, track); + public ErrorNumber ReadSector(ulong sectorAddress, uint track, out byte[] buffer) => + ReadSectors(sectorAddress, 1, track, out buffer); /// public byte[] ReadSectorTag(ulong sectorAddress, uint track, SectorTagType tag) => @@ -831,11 +832,7 @@ namespace Aaru.DiscImages from track in Tracks where track.Sequence == kvp.Key where sectorAddress - kvp.Value < track.EndSector - track.StartSector + 1 select kvp) - { - buffer = ReadSectors(sectorAddress - kvp.Value, length, kvp.Key); - - return ErrorNumber.NoError; - } + return ReadSectors(sectorAddress - kvp.Value, length, kvp.Key, out buffer); return ErrorNumber.SectorNotFound; } @@ -859,26 +856,17 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSectors(ulong sectorAddress, uint length, uint track) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, uint track, out byte[] buffer) { - var aaruTrack = new Track - { - Sequence = 0 - }; + buffer = null; - foreach(Track linqTrack in Tracks.Where(linqTrack => linqTrack.Sequence == track)) - { - aaruTrack = linqTrack; - - break; - } + Track? aaruTrack = Tracks.FirstOrDefault(linqTrack => linqTrack.Sequence == track); if(aaruTrack is null) - throw new ArgumentOutOfRangeException(nameof(track), "Track does not exist in disc image"); + return ErrorNumber.SectorNotFound; if(length + sectorAddress > aaruTrack.EndSector - aaruTrack.StartSector + 1) - throw new ArgumentOutOfRangeException(nameof(length), - $"Requested more sectors ({length + sectorAddress}) than present in track ({aaruTrack.EndSector - aaruTrack.StartSector + 1}), won't cross tracks"); + return ErrorNumber.OutOfRange; uint sectorOffset; uint sectorSize; @@ -919,7 +907,7 @@ namespace Aaru.DiscImages } break; - default: throw new FeatureSupportedButNotImplementedImageException("Unsupported track type"); + default: return ErrorNumber.NotSupported; } switch(aaruTrack.SubchannelType) @@ -936,10 +924,10 @@ namespace Aaru.DiscImages sectorSkip += 96; break; - default: throw new FeatureSupportedButNotImplementedImageException("Unsupported subchannel type"); + default: return ErrorNumber.NotSupported; } - byte[] buffer = new byte[sectorSize * length]; + buffer = new byte[sectorSize * length]; _imageStream.Seek((long)(aaruTrack.FileOffset + (sectorAddress * (sectorOffset + sectorSize + sectorSkip))), SeekOrigin.Begin); @@ -977,7 +965,7 @@ namespace Aaru.DiscImages Array.Copy(sector, 0, buffer, i * sectorSize, sectorSize); } - return buffer; + return ErrorNumber.NoError; } /// @@ -1273,7 +1261,11 @@ namespace Aaru.DiscImages public byte[] ReadSectorsLong(ulong sectorAddress, uint length, uint track) { if(!_isCd) - return ReadSectors(sectorAddress, length, track); + { + ErrorNumber errno = ReadSectors(sectorAddress, length, track, out byte[] nonCdBuffer); + + return errno == ErrorNumber.NoError ? nonCdBuffer : null; + } var aaruTrack = new Track { diff --git a/Aaru.Images/GDI/Read.cs b/Aaru.Images/GDI/Read.cs index 608f107ac..d005e0623 100644 --- a/Aaru.Images/GDI/Read.cs +++ b/Aaru.Images/GDI/Read.cs @@ -332,7 +332,8 @@ namespace Aaru.DiscImages ReadSectorsTag(sectorAddress, 1, tag, out buffer); /// - public byte[] ReadSector(ulong sectorAddress, uint track) => ReadSectors(sectorAddress, 1, track); + public ErrorNumber ReadSector(ulong sectorAddress, uint track, out byte[] buffer) => + ReadSectors(sectorAddress, 1, track, out buffer); /// public byte[] ReadSectorTag(ulong sectorAddress, uint track, SectorTagType tag) => @@ -347,11 +348,7 @@ namespace Aaru.DiscImages from gdiTrack in _discImage.Tracks where gdiTrack.Sequence == kvp.Key where sectorAddress - kvp.Value < gdiTrack.Sectors select kvp) - { - buffer = ReadSectors(sectorAddress - kvp.Value, length, kvp.Key); - - return ErrorNumber.NoError; - } + return ReadSectors(sectorAddress - kvp.Value, length, kvp.Key, out buffer); _offsetMap.TryGetValue(0, out ulong transitionStart); @@ -359,9 +356,7 @@ namespace Aaru.DiscImages sectorAddress >= _densitySeparationSectors + transitionStart) return ErrorNumber.SectorNotFound; - buffer = ReadSectors(sectorAddress - transitionStart, length, 0); - - return ErrorNumber.NoError; + return ReadSectors(sectorAddress - transitionStart, length, 0, out buffer); } /// @@ -391,15 +386,18 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSectors(ulong sectorAddress, uint length, uint track) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, uint track, out byte[] buffer) { + buffer = null; + if(track == 0) { if(sectorAddress + length > _densitySeparationSectors) - throw new ArgumentOutOfRangeException(nameof(length), - "Requested more sectors than present in track, won't cross tracks"); + return ErrorNumber.OutOfRange; - return new byte[length * 2352]; + buffer = new byte[length * 2352]; + + return ErrorNumber.NoError; } var aaruTrack = new GdiTrack @@ -415,11 +413,10 @@ namespace Aaru.DiscImages } if(aaruTrack.Sequence == 0) - throw new ArgumentOutOfRangeException(nameof(track), "Track does not exist in disc image"); + return ErrorNumber.SectorNotFound; if(sectorAddress + length > aaruTrack.Sectors) - throw new ArgumentOutOfRangeException(nameof(length), - "Requested more sectors than present in track, won't cross tracks"); + return ErrorNumber.OutOfRange; uint sectorOffset; uint sectorSize; @@ -452,10 +449,10 @@ namespace Aaru.DiscImages break; } - default: throw new FeatureSupportedButNotImplementedImageException("Unsupported track type"); + default: return ErrorNumber.NotSupported; } - byte[] buffer = new byte[sectorSize * length]; + buffer = new byte[sectorSize * length]; ulong remainingSectors = length; @@ -468,7 +465,7 @@ namespace Aaru.DiscImages } if(remainingSectors == 0) - return buffer; + return ErrorNumber.NoError; _imageStream = aaruTrack.TrackFilter.GetDataForkStream(); var br = new BinaryReader(_imageStream); @@ -484,9 +481,7 @@ namespace Aaru.DiscImages if(sectorOffset == 0 && sectorSkip == 0 && remainingSectors == length) - { buffer = br.ReadBytes((int)(sectorSize * remainingSectors)); - } else if(sectorOffset == 0 && sectorSkip == 0) { @@ -507,7 +502,7 @@ namespace Aaru.DiscImages } } - return buffer; + return ErrorNumber.NoError; } /// diff --git a/Aaru.Images/Nero/Read.cs b/Aaru.Images/Nero/Read.cs index 8a89923dc..0f8ffa465 100644 --- a/Aaru.Images/Nero/Read.cs +++ b/Aaru.Images/Nero/Read.cs @@ -1593,7 +1593,8 @@ namespace Aaru.DiscImages ReadSectorsTag(sectorAddress, 1, tag, out buffer); /// - public byte[] ReadSector(ulong sectorAddress, uint track) => ReadSectors(sectorAddress, 1, track); + public ErrorNumber ReadSector(ulong sectorAddress, uint track, out byte[] buffer) => + ReadSectors(sectorAddress, 1, track, out buffer); /// public byte[] ReadSectorTag(ulong sectorAddress, uint track, SectorTagType tag) => @@ -1608,11 +1609,7 @@ namespace Aaru.DiscImages from track in Tracks where track.Sequence == kvp.Key where sectorAddress - kvp.Value <= track.EndSector - track.StartSector select kvp) - { - buffer = ReadSectors(sectorAddress - kvp.Value, length, kvp.Key); - - return ErrorNumber.NoError; - } + return ReadSectors(sectorAddress - kvp.Value, length, kvp.Key, out buffer); return ErrorNumber.SectorNotFound; } @@ -1636,14 +1633,15 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSectors(ulong sectorAddress, uint length, uint track) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, uint track, out byte[] buffer) { + buffer = null; + if(!_neroTracks.TryGetValue(track, out NeroTrack aaruTrack)) - throw new ArgumentOutOfRangeException(nameof(track), "Track not found"); + return ErrorNumber.SectorNotFound; if(length > aaruTrack.Sectors) - throw new ArgumentOutOfRangeException(nameof(length), - $"Requested more sectors ({length}) than present in track ({aaruTrack.Sectors}), won't cross tracks"); + return ErrorNumber.OutOfRange; uint sectorOffset; uint sectorSize; @@ -1729,10 +1727,10 @@ namespace Aaru.DiscImages break; } - default: throw new FeatureSupportedButNotImplementedImageException("Unsupported track type"); + default: return ErrorNumber.NotSupported; } - byte[] buffer = new byte[sectorSize * length]; + buffer = new byte[sectorSize * length]; _imageStream = _neroFilter.GetDataForkStream(); var br = new BinaryReader(_imageStream); @@ -1769,7 +1767,7 @@ namespace Aaru.DiscImages Array.Copy(sector, 0, buffer, i * sectorSize, sectorSize); } - return buffer; + return ErrorNumber.NoError; } /// @@ -2117,7 +2115,11 @@ namespace Aaru.DiscImages public byte[] ReadSectorsLong(ulong sectorAddress, uint length, uint track) { if(!_isCd) - return ReadSectors(sectorAddress, length, track); + { + ErrorNumber errno = ReadSectors(sectorAddress, length, track, out byte[] nonCdBuffer); + + return errno == ErrorNumber.NoError ? nonCdBuffer : null; + } if(!_neroTracks.TryGetValue(track, out NeroTrack aaruTrack)) throw new ArgumentOutOfRangeException(nameof(track), "Track not found"); diff --git a/Aaru.Images/ZZZRawImage/Read.cs b/Aaru.Images/ZZZRawImage/Read.cs index b40571c78..1386fb852 100644 --- a/Aaru.Images/ZZZRawImage/Read.cs +++ b/Aaru.Images/ZZZRawImage/Read.cs @@ -1344,31 +1344,25 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSector(ulong sectorAddress, uint track) + public ErrorNumber ReadSector(ulong sectorAddress, uint track, out byte[] buffer) { + buffer = null; + if(_imageInfo.XmlMediaType != XmlMediaType.OpticalDisc) - throw new FeatureUnsupportedImageException("Feature not supported by image format"); + return ErrorNumber.NotSupported; - if(track != 1) - throw new ArgumentOutOfRangeException(nameof(track), "Only a single track is supported"); - - ErrorNumber errno = ReadSector(sectorAddress, out byte[] buffer); - - return errno == ErrorNumber.NoError ? buffer : null; + return track != 1 ? ErrorNumber.OutOfRange : ReadSector(sectorAddress, out buffer); } /// - public byte[] ReadSectors(ulong sectorAddress, uint length, uint track) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, uint track, out byte[] buffer) { + buffer = null; + if(_imageInfo.XmlMediaType != XmlMediaType.OpticalDisc) - throw new FeatureUnsupportedImageException("Feature not supported by image format"); + return ErrorNumber.NotSupported; - if(track != 1) - throw new ArgumentOutOfRangeException(nameof(track), "Only a single track is supported"); - - ErrorNumber errno = ReadSectors(sectorAddress, length, out byte[] buffer); - - return errno == ErrorNumber.NoError ? buffer : null; + return track != 1 ? ErrorNumber.OutOfRange : ReadSectors(sectorAddress, length, out buffer); } /// diff --git a/Aaru.Tests/Images/OpticalMediaImageTest.cs b/Aaru.Tests/Images/OpticalMediaImageTest.cs index 5741c73f5..665425500 100644 --- a/Aaru.Tests/Images/OpticalMediaImageTest.cs +++ b/Aaru.Tests/Images/OpticalMediaImageTest.cs @@ -344,25 +344,37 @@ namespace Aaru.Tests.Images if(sectors - doneSectors >= SECTORS_TO_READ) { - sector = - @long ? image.ReadSectorsLong(doneSectors, SECTORS_TO_READ, - currentTrack.Sequence) - : image.ReadSectors(doneSectors, SECTORS_TO_READ, - currentTrack.Sequence); + if(@long) + { + errno = ErrorNumber.NoError; + + sector = image.ReadSectorsLong(doneSectors, SECTORS_TO_READ, + currentTrack.Sequence); + } + else + errno = image.ReadSectors(doneSectors, SECTORS_TO_READ, + currentTrack.Sequence, out sector); doneSectors += SECTORS_TO_READ; } else { - sector = - @long ? image.ReadSectorsLong(doneSectors, (uint)(sectors - doneSectors), - currentTrack.Sequence) - : image.ReadSectors(doneSectors, (uint)(sectors - doneSectors), - currentTrack.Sequence); + if(@long) + { + errno = ErrorNumber.NoError; + + sector = image.ReadSectorsLong(doneSectors, (uint)(sectors - doneSectors), + currentTrack.Sequence); + } + else + errno = image.ReadSectors(doneSectors, (uint)(sectors - doneSectors), + currentTrack.Sequence, out sector); doneSectors += sectors - doneSectors; } + Assert.AreEqual(ErrorNumber.NoError, errno); + ctx.Update(sector); } } diff --git a/Aaru.Tests/Issues/OpticalImageReadIssueTest.cs b/Aaru.Tests/Issues/OpticalImageReadIssueTest.cs index e93cefa53..96ddc91b4 100644 --- a/Aaru.Tests/Issues/OpticalImageReadIssueTest.cs +++ b/Aaru.Tests/Issues/OpticalImageReadIssueTest.cs @@ -48,6 +48,7 @@ namespace Aaru.Tests.Issues ulong previousTrackEnd = 0; List inputTracks = opticalInput.Tracks; + ErrorNumber errno; foreach(Track currentTrack in inputTracks) { @@ -60,18 +61,21 @@ namespace Aaru.Tests.Issues if(sectors - doneSectors >= SECTORS_TO_READ) { - sector = opticalInput.ReadSectors(doneSectors, SECTORS_TO_READ, currentTrack.Sequence); + errno = opticalInput.ReadSectors(doneSectors, SECTORS_TO_READ, currentTrack.Sequence, + out sector); doneSectors += SECTORS_TO_READ; } else { - sector = opticalInput.ReadSectors(doneSectors, (uint)(sectors - doneSectors), - currentTrack.Sequence); + errno = opticalInput.ReadSectors(doneSectors, (uint)(sectors - doneSectors), + currentTrack.Sequence, out sector); doneSectors += sectors - doneSectors; } + Assert.AreEqual(ErrorNumber.NoError, errno); + ctx.Update(sector); } } diff --git a/Aaru.Tests/WritableImages/WritableOpticalMediaImageTest.cs b/Aaru.Tests/WritableImages/WritableOpticalMediaImageTest.cs index 9ea9b627d..d3aaafefb 100644 --- a/Aaru.Tests/WritableImages/WritableOpticalMediaImageTest.cs +++ b/Aaru.Tests/WritableImages/WritableOpticalMediaImageTest.cs @@ -575,24 +575,37 @@ namespace Aaru.Tests.WritableImages if(sectors - doneSectors >= SECTORS_TO_READ) { - sector = - @long ? image.ReadSectorsLong(doneSectors, SECTORS_TO_READ, - currentTrack.Sequence) - : image.ReadSectors(doneSectors, SECTORS_TO_READ, currentTrack.Sequence); + if(@long) + { + sector = image.ReadSectorsLong(doneSectors, SECTORS_TO_READ, + currentTrack.Sequence); + + errno = ErrorNumber.NoError; + } + else + errno = image.ReadSectors(doneSectors, SECTORS_TO_READ, currentTrack.Sequence, + out sector); doneSectors += SECTORS_TO_READ; } else { - sector = - @long ? image.ReadSectorsLong(doneSectors, (uint)(sectors - doneSectors), - currentTrack.Sequence) - : image.ReadSectors(doneSectors, (uint)(sectors - doneSectors), - currentTrack.Sequence); + if(@long) + { + sector = image.ReadSectorsLong(doneSectors, (uint)(sectors - doneSectors), + currentTrack.Sequence); + + errno = ErrorNumber.NoError; + } + else + errno = image.ReadSectors(doneSectors, (uint)(sectors - doneSectors), + currentTrack.Sequence, out sector); doneSectors += sectors - doneSectors; } + Assert.AreEqual(ErrorNumber.NoError, errno); + ctx.Update(sector); } } diff --git a/Aaru/Commands/Image/Checksum.cs b/Aaru/Commands/Image/Checksum.cs index 75f0e4db3..71e45c6a8 100644 --- a/Aaru/Commands/Image/Checksum.cs +++ b/Aaru/Commands/Image/Checksum.cs @@ -369,26 +369,43 @@ namespace Aaru.Commands.Image if(sectors - doneSectors >= SECTORS_TO_READ) { - sector = opticalInput.ReadSectors(doneSectors, SECTORS_TO_READ, - currentTrack.Sequence); + errno = opticalInput.ReadSectors(doneSectors, SECTORS_TO_READ, + currentTrack.Sequence, out sector); trackTask.Description = string.Format("Hashing sectors {0} to {2} of track {1}", doneSectors, currentTrack.Sequence, doneSectors + SECTORS_TO_READ); + if(errno != ErrorNumber.NoError) + { + AaruConsole. + ErrorWriteLine($"Error {errno} while reading {SECTORS_TO_READ} sectors from sector {doneSectors}, not continuing..."); + + return; + } + doneSectors += SECTORS_TO_READ; } else { - sector = opticalInput.ReadSectors(doneSectors, - (uint)(sectors - doneSectors), currentTrack.Sequence); + errno = opticalInput.ReadSectors(doneSectors, + (uint)(sectors - doneSectors), currentTrack.Sequence, + out sector); trackTask.Description = string.Format("Hashing sectors {0} to {2} of track {1}", doneSectors, currentTrack.Sequence, doneSectors + (sectors - doneSectors)); + if(errno != ErrorNumber.NoError) + { + AaruConsole. + ErrorWriteLine($"Error {errno} while reading {sectors - doneSectors} sectors from sector {doneSectors}, not continuing..."); + + return; + } + doneSectors += sectors - doneSectors; }