diff --git a/Aaru.CommonTypes b/Aaru.CommonTypes index 0046bdd04..5bc77788e 160000 --- a/Aaru.CommonTypes +++ b/Aaru.CommonTypes @@ -1 +1 @@ -Subproject commit 0046bdd046809dd51eef9758b28c188efc7a5d14 +Subproject commit 5bc77788ece229aac83b0605b6652f1e56db3d5c diff --git a/Aaru.Core/Entropy.cs b/Aaru.Core/Entropy.cs index a075e8e53..635dd39e2 100644 --- a/Aaru.Core/Entropy.cs +++ b/Aaru.Core/Entropy.cs @@ -35,6 +35,7 @@ using System.Collections.Generic; using System.Linq; using Aaru.Checksums; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Aaru.CommonTypes.Structs; using Aaru.Console; @@ -74,7 +75,7 @@ namespace Aaru.Core /// Calculated entropy public EntropyResults[] CalculateTracksEntropy(bool duplicatedSectors) { - List entropyResults = new List(); + List entropyResults = new(); if(!(_inputFormat is IOpticalMediaImage opticalMediaImage)) { @@ -103,7 +104,7 @@ namespace Aaru.Core ulong[] entTable = new ulong[256]; ulong trackSize = 0; - List uniqueSectorsPerTrack = new List(); + List uniqueSectorsPerTrack = new(); trackEntropy.Sectors = currentTrack.EndSector - currentTrack.StartSector + 1; @@ -169,7 +170,7 @@ namespace Aaru.Core ulong[] entTable = new ulong[256]; ulong diskSize = 0; - List uniqueSectors = new List(); + List uniqueSectors = new(); entropy.Sectors = _inputFormat.Info.Sectors; AaruConsole.WriteLine("Sectors {0}", entropy.Sectors); @@ -178,7 +179,14 @@ namespace Aaru.Core for(ulong i = 0; i < entropy.Sectors; i++) { UpdateProgressEvent?.Invoke($"Entropying sector {i + 1}", (long)(i + 1), (long)entropy.Sectors); - byte[] sector = _inputFormat.ReadSector(i); + ErrorNumber errno = _inputFormat.ReadSector(i, out byte[] sector); + + if(errno != ErrorNumber.NoError) + { + AaruConsole.ErrorWriteLine($"Error {errno} while reading sector {i}, continuing..."); + + continue; + } if(duplicatedSectors) { diff --git a/Aaru.Core/Sidecar/BlockMedia.cs b/Aaru.Core/Sidecar/BlockMedia.cs index 0b1b9f8b8..860339e73 100644 --- a/Aaru.Core/Sidecar/BlockMedia.cs +++ b/Aaru.Core/Sidecar/BlockMedia.cs @@ -413,13 +413,31 @@ namespace Aaru.Core if(sectors - doneSectors >= sectorsToRead) { - sector = image.ReadSectors(doneSectors, sectorsToRead); + errno = image.ReadSectors(doneSectors, sectorsToRead, out sector); + + if(errno != ErrorNumber.NoError) + { + AaruConsole.ErrorWriteLine($"Error {errno} reading sector {doneSectors}"); + EndProgress2(); + + return; + } + UpdateProgress2("Hashing sector {0} of {1}", (long)doneSectors, (long)sectors); doneSectors += sectorsToRead; } else { - sector = image.ReadSectors(doneSectors, (uint)(sectors - doneSectors)); + errno = image.ReadSectors(doneSectors, (uint)(sectors - doneSectors), out sector); + + if(errno != ErrorNumber.NoError) + { + AaruConsole.ErrorWriteLine($"Error {errno} reading sector {doneSectors}"); + EndProgress2(); + + return; + } + UpdateProgress2("Hashing sector {0} of {1}", (long)doneSectors, (long)sectors); doneSectors += sectors - doneSectors; } @@ -497,14 +515,36 @@ namespace Aaru.Core if(sectors - doneSectors >= sectorsToRead) { - sector = image.ReadSectors(tapePartition.FirstBlock + doneSectors, sectorsToRead); + errno = image.ReadSectors(tapePartition.FirstBlock + doneSectors, sectorsToRead, + out sector); + + if(errno != ErrorNumber.NoError) + { + AaruConsole. + ErrorWriteLine($"Error {errno} reading sector {tapePartition.FirstBlock + doneSectors}"); + + EndProgress2(); + + return; + } + UpdateProgress2("Hashing blocks {0} of {1}", (long)doneSectors, (long)sectors); doneSectors += sectorsToRead; } else { - sector = image.ReadSectors(tapePartition.FirstBlock + doneSectors, - (uint)(sectors - doneSectors)); + errno = image.ReadSectors(tapePartition.FirstBlock + doneSectors, + (uint)(sectors - doneSectors), out sector); + + if(errno != ErrorNumber.NoError) + { + AaruConsole. + ErrorWriteLine($"Error {errno} reading sector {tapePartition.FirstBlock + doneSectors}"); + + EndProgress2(); + + return; + } UpdateProgress2("Hashing blocks {0} of {1}", (long)doneSectors, (long)sectors); doneSectors += sectors - doneSectors; @@ -575,14 +615,36 @@ namespace Aaru.Core if(sectors - doneSectors >= sectorsToRead) { - sector = image.ReadSectors(tapeFile.FirstBlock + doneSectors, sectorsToRead); + errno = image.ReadSectors(tapeFile.FirstBlock + doneSectors, sectorsToRead, + out sector); + + if(errno != ErrorNumber.NoError) + { + AaruConsole. + ErrorWriteLine($"Error {errno} reading sector {tapeFile.FirstBlock + doneSectors}"); + + EndProgress2(); + + return; + } + UpdateProgress2("Hashing blocks {0} of {1}", (long)doneSectors, (long)sectors); doneSectors += sectorsToRead; } else { - sector = image.ReadSectors(tapeFile.FirstBlock + doneSectors, - (uint)(sectors - doneSectors)); + errno = image.ReadSectors(tapeFile.FirstBlock + doneSectors, + (uint)(sectors - doneSectors), out sector); + + if(errno != ErrorNumber.NoError) + { + AaruConsole. + ErrorWriteLine($"Error {errno} reading sector {tapeFile.FirstBlock + doneSectors}"); + + EndProgress2(); + + return; + } UpdateProgress2("Hashing blocks {0} of {1}", (long)doneSectors, (long)sectors); doneSectors += sectors - doneSectors; diff --git a/Aaru.Filesystems/AODOS.cs b/Aaru.Filesystems/AODOS.cs index ac436cc06..ec6a4915f 100644 --- a/Aaru.Filesystems/AODOS.cs +++ b/Aaru.Filesystems/AODOS.cs @@ -35,6 +35,7 @@ using System.Linq; using System.Runtime.InteropServices; using System.Text; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Aaru.Helpers; using Schemas; @@ -57,7 +58,7 @@ namespace Aaru.Filesystems /// public string Name => "Alexander Osipov DOS file system"; /// - public Guid Id => new Guid("668E5039-9DDD-442A-BE1B-A315D6E38E26"); + public Guid Id => new("668E5039-9DDD-442A-BE1B-A315D6E38E26"); /// public Encoding Encoding { get; private set; } /// @@ -79,8 +80,12 @@ namespace Aaru.Filesystems imagePlugin.Info.Sectors != 1600) return false; - byte[] sector = imagePlugin.ReadSector(0); - BootBlock bb = Marshal.ByteArrayToStructureLittleEndian(sector); + ErrorNumber errno = imagePlugin.ReadSector(0, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return false; + + BootBlock bb = Marshal.ByteArrayToStructureLittleEndian(sector); return bb.identifier.SequenceEqual(_identifier); } @@ -89,9 +94,14 @@ namespace Aaru.Filesystems public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information, Encoding encoding) { - Encoding = Encoding.GetEncoding("koi8-r"); - byte[] sector = imagePlugin.ReadSector(0); - BootBlock bb = Marshal.ByteArrayToStructureLittleEndian(sector); + information = ""; + Encoding = Encoding.GetEncoding("koi8-r"); + ErrorNumber errno = imagePlugin.ReadSector(0, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return; + + BootBlock bb = Marshal.ByteArrayToStructureLittleEndian(sector); var sbInformation = new StringBuilder(); diff --git a/Aaru.Filesystems/APFS.cs b/Aaru.Filesystems/APFS.cs index 77edd9a41..a5faa3bec 100644 --- a/Aaru.Filesystems/APFS.cs +++ b/Aaru.Filesystems/APFS.cs @@ -35,6 +35,7 @@ using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; using System.Text; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Schemas; using Marshal = Aaru.Helpers.Marshal; @@ -56,7 +57,7 @@ namespace Aaru.Filesystems /// public string Name => "Apple File System"; /// - public Guid Id => new Guid("A4060F9D-2909-42E2-9D95-DB31FA7EA797"); + public Guid Id => new("A4060F9D-2909-42E2-9D95-DB31FA7EA797"); /// public string Author => "Natalia Portillo"; @@ -66,7 +67,11 @@ namespace Aaru.Filesystems if(partition.Start >= partition.End) return false; - byte[] sector = imagePlugin.ReadSector(partition.Start); + ErrorNumber errno = imagePlugin.ReadSector(partition.Start, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return false; + ContainerSuperBlock nxSb; try @@ -93,7 +98,11 @@ namespace Aaru.Filesystems if(partition.Start >= partition.End) return; - byte[] sector = imagePlugin.ReadSector(partition.Start); + ErrorNumber errno = imagePlugin.ReadSector(partition.Start, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return; + ContainerSuperBlock nxSb; try diff --git a/Aaru.Filesystems/Acorn.cs b/Aaru.Filesystems/Acorn.cs index c52dc1b5b..45993442e 100644 --- a/Aaru.Filesystems/Acorn.cs +++ b/Aaru.Filesystems/Acorn.cs @@ -35,6 +35,7 @@ using System.Collections.Generic; using System.Runtime.InteropServices; using System.Text; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Aaru.Console; using Aaru.Helpers; @@ -70,7 +71,7 @@ namespace Aaru.Filesystems /// public string Name => "Acorn Advanced Disc Filing System"; /// - public Guid Id => new Guid("BAFC1E50-9C64-4CD3-8400-80628CC27AFA"); + public Guid Id => new("BAFC1E50-9C64-4CD3-8400-80628CC27AFA"); /// public Encoding Encoding { get; private set; } /// @@ -89,16 +90,25 @@ namespace Aaru.Filesystems if(imagePlugin.Info.SectorSize < 256) return false; - byte[] sector; + byte[] sector; + ErrorNumber errno; // ADFS-S, ADFS-M, ADFS-L, ADFS-D without partitions if(partition.Start == 0) { - sector = imagePlugin.ReadSector(0); + errno = imagePlugin.ReadSector(0, out sector); + + if(errno != ErrorNumber.NoError) + return false; + byte oldChk0 = AcornMapChecksum(sector, 255); OldMapSector0 oldMap0 = Marshal.ByteArrayToStructureLittleEndian(sector); - sector = imagePlugin.ReadSector(1); + errno = imagePlugin.ReadSector(1, out sector); + + if(errno != ErrorNumber.NoError) + return false; + byte oldChk1 = AcornMapChecksum(sector, 255); OldMapSector1 oldMap1 = Marshal.ByteArrayToStructureLittleEndian(sector); @@ -110,7 +120,11 @@ namespace Aaru.Filesystems oldMap1.checksum != oldChk1 && sector.Length >= 512) { - sector = imagePlugin.ReadSector(0); + errno = imagePlugin.ReadSector(0, out sector); + + if(errno != ErrorNumber.NoError) + return false; + byte[] tmp = new byte[256]; Array.Copy(sector, 256, tmp, 0, 256); oldChk1 = AcornMapChecksum(tmp, 255); @@ -131,7 +145,10 @@ namespace Aaru.Filesystems if(OLD_DIRECTORY_SIZE % imagePlugin.Info.SectorSize > 0) sectorsToRead++; - sector = imagePlugin.ReadSectors(sbSector, sectorsToRead); + errno = imagePlugin.ReadSectors(sbSector, sectorsToRead, out sector); + + if(errno != ErrorNumber.NoError) + return false; if(sector.Length > OLD_DIRECTORY_SIZE) { @@ -165,7 +182,10 @@ namespace Aaru.Filesystems if(NEW_DIRECTORY_SIZE % imagePlugin.Info.SectorSize > 0) sectorsToRead++; - sector = imagePlugin.ReadSectors(sbSector, sectorsToRead); + errno = imagePlugin.ReadSectors(sbSector, sectorsToRead, out sector); + + if(errno != ErrorNumber.NoError) + return false; if(sector.Length > OLD_DIRECTORY_SIZE) { @@ -197,7 +217,11 @@ namespace Aaru.Filesystems // Partitioning or not, new formats follow: DiscRecord drSb; - sector = imagePlugin.ReadSector(partition.Start); + errno = imagePlugin.ReadSector(partition.Start, out sector); + + if(errno != ErrorNumber.NoError) + return false; + byte newChk = NewMapChecksum(sector); AaruConsole.DebugWriteLine("ADFS Plugin", "newChk = {0}", newChk); AaruConsole.DebugWriteLine("ADFS Plugin", "map.zoneChecksum = {0}", sector[0]); @@ -211,8 +235,12 @@ namespace Aaru.Filesystems if(sbSector + partition.Start + sectorsToRead >= partition.End) return false; - byte[] bootSector = imagePlugin.ReadSectors(sbSector + partition.Start, sectorsToRead); - int bootChk = 0; + errno = imagePlugin.ReadSectors(sbSector + partition.Start, sectorsToRead, out byte[] bootSector); + + if(errno != ErrorNumber.NoError) + return false; + + int bootChk = 0; if(bootSector.Length < 512) return false; @@ -277,6 +305,7 @@ namespace Aaru.Filesystems var sbInformation = new StringBuilder(); XmlFsType = new FileSystemType(); information = ""; + ErrorNumber errno; ulong sbSector; byte[] sector; @@ -286,11 +315,19 @@ namespace Aaru.Filesystems // ADFS-S, ADFS-M, ADFS-L, ADFS-D without partitions if(partition.Start == 0) { - sector = imagePlugin.ReadSector(0); + errno = imagePlugin.ReadSector(0, out sector); + + if(errno != ErrorNumber.NoError) + return; + byte oldChk0 = AcornMapChecksum(sector, 255); OldMapSector0 oldMap0 = Marshal.ByteArrayToStructureLittleEndian(sector); - sector = imagePlugin.ReadSector(1); + errno = imagePlugin.ReadSector(1, out sector); + + if(errno != ErrorNumber.NoError) + return; + byte oldChk1 = AcornMapChecksum(sector, 255); OldMapSector1 oldMap1 = Marshal.ByteArrayToStructureLittleEndian(sector); @@ -299,7 +336,11 @@ namespace Aaru.Filesystems oldMap1.checksum != oldChk1 && sector.Length >= 512) { - sector = imagePlugin.ReadSector(0); + errno = imagePlugin.ReadSector(0, out sector); + + if(errno != ErrorNumber.NoError) + return; + byte[] tmp = new byte[256]; Array.Copy(sector, 256, tmp, 0, 256); oldChk1 = AcornMapChecksum(tmp, 255); @@ -336,7 +377,10 @@ namespace Aaru.Filesystems if(OLD_DIRECTORY_SIZE % imagePlugin.Info.SectorSize > 0) sectorsToRead++; - sector = imagePlugin.ReadSectors(sbSector, sectorsToRead); + errno = imagePlugin.ReadSectors(sbSector, sectorsToRead, out sector); + + if(errno != ErrorNumber.NoError) + return; if(sector.Length > OLD_DIRECTORY_SIZE) { @@ -360,7 +404,10 @@ namespace Aaru.Filesystems if(NEW_DIRECTORY_SIZE % imagePlugin.Info.SectorSize > 0) sectorsToRead++; - sector = imagePlugin.ReadSectors(sbSector, sectorsToRead); + errno = imagePlugin.ReadSectors(sbSector, sectorsToRead, out sector); + + if(errno != ErrorNumber.NoError) + return; if(sector.Length > OLD_DIRECTORY_SIZE) { @@ -379,7 +426,10 @@ namespace Aaru.Filesystems namebytes = oldRoot.tail.name; else { - sector = imagePlugin.ReadSectors(sbSector, sectorsToRead); + errno = imagePlugin.ReadSectors(sbSector, sectorsToRead, out sector); + + if(errno != ErrorNumber.NoError) + return; if(sector.Length > NEW_DIRECTORY_SIZE) { @@ -426,7 +476,11 @@ namespace Aaru.Filesystems // Partitioning or not, new formats follow: DiscRecord drSb; - sector = imagePlugin.ReadSector(partition.Start); + errno = imagePlugin.ReadSector(partition.Start, out sector); + + if(errno != ErrorNumber.NoError) + return; + byte newChk = NewMapChecksum(sector); AaruConsole.DebugWriteLine("ADFS Plugin", "newChk = {0}", newChk); AaruConsole.DebugWriteLine("ADFS Plugin", "map.zoneChecksum = {0}", sector[0]); @@ -437,8 +491,12 @@ namespace Aaru.Filesystems if(BOOT_BLOCK_SIZE % imagePlugin.Info.SectorSize > 0) sectorsToRead++; - byte[] bootSector = imagePlugin.ReadSectors(sbSector + partition.Start, sectorsToRead); - int bootChk = 0; + errno = imagePlugin.ReadSectors(sbSector + partition.Start, sectorsToRead, out byte[] bootSector); + + if(errno != ErrorNumber.NoError) + return; + + int bootChk = 0; for(int i = 0; i < 0x1FF; i++) bootChk = (bootChk & 0xFF) + (bootChk >> 8) + bootSector[i]; diff --git a/Aaru.Filesystems/AmigaDOS.cs b/Aaru.Filesystems/AmigaDOS.cs index 9ba8dc45a..c8fc726eb 100644 --- a/Aaru.Filesystems/AmigaDOS.cs +++ b/Aaru.Filesystems/AmigaDOS.cs @@ -36,6 +36,7 @@ using System.Runtime.InteropServices; using System.Text; using Aaru.Checksums; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Aaru.Console; using Aaru.Helpers; @@ -59,7 +60,7 @@ namespace Aaru.Filesystems /// public string Name => "Amiga DOS filesystem"; /// - public Guid Id => new Guid("3c882400-208c-427d-a086-9119852a1bc7"); + public Guid Id => new("3c882400-208c-427d-a086-9119852a1bc7"); /// public Encoding Encoding { get; private set; } /// @@ -77,8 +78,12 @@ namespace Aaru.Filesystems // However while you can set a block size different from the sector size on formatting, the bootblock block // size for floppies is the sector size, and for RDB is usually is the hard disk sector size, // so this is not entirely wrong... - byte[] sector = imagePlugin.ReadSectors(0 + partition.Start, 2); - BootBlock bblk = Marshal.ByteArrayToStructureBigEndian(sector); + ErrorNumber errno = imagePlugin.ReadSectors(0 + partition.Start, 2, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return false; + + BootBlock bblk = Marshal.ByteArrayToStructureBigEndian(sector); // AROS boot floppies... if(sector.Length >= 512 && @@ -87,8 +92,12 @@ namespace Aaru.Filesystems (bblk.diskType & FFS_MASK) != FFS_MASK && (bblk.diskType & MUFS_MASK) != MUFS_MASK) { - sector = imagePlugin.ReadSectors(1 + partition.Start, 2); - bblk = Marshal.ByteArrayToStructureBigEndian(sector); + errno = imagePlugin.ReadSectors(1 + partition.Start, 2, out sector); + + if(errno != ErrorNumber.NoError) + return false; + + bblk = Marshal.ByteArrayToStructureBigEndian(sector); } // Not FFS or MuFS? @@ -127,7 +136,10 @@ namespace Aaru.Filesystems { AaruConsole.DebugWriteLine("AmigaDOS plugin", "Searching for Rootblock in sector {0}", rootPtr); - sector = imagePlugin.ReadSector(rootPtr); + errno = imagePlugin.ReadSector(rootPtr, out sector); + + if(errno != ErrorNumber.NoError) + continue; rblk.type = BigEndianBitConverter.ToUInt32(sector, 0x00); AaruConsole.DebugWriteLine("AmigaDOS plugin", "rblk.type = {0}", rblk.type); @@ -151,7 +163,10 @@ namespace Aaru.Filesystems if(rootPtr + sectorsPerBlock >= partition.End) continue; - sector = imagePlugin.ReadSectors(rootPtr, sectorsPerBlock); + errno = imagePlugin.ReadSectors(rootPtr, sectorsPerBlock, out sector); + + if(errno != ErrorNumber.NoError) + continue; // Clear checksum on sector rblk.checksum = BigEndianBitConverter.ToUInt32(sector, 20); @@ -180,7 +195,10 @@ namespace Aaru.Filesystems var sbInformation = new StringBuilder(); XmlFsType = new FileSystemType(); information = null; - byte[] bootBlockSectors = imagePlugin.ReadSectors(0 + partition.Start, 2); + ErrorNumber errno = imagePlugin.ReadSectors(0 + partition.Start, 2, out byte[] bootBlockSectors); + + if(errno != ErrorNumber.NoError) + return; BootBlock bootBlk = Marshal.ByteArrayToStructureBigEndian(bootBlockSectors); bootBlk.bootCode = new byte[bootBlockSectors.Length - 12]; @@ -216,7 +234,10 @@ namespace Aaru.Filesystems { AaruConsole.DebugWriteLine("AmigaDOS plugin", "Searching for Rootblock in sector {0}", rootPtr); - rootBlockSector = imagePlugin.ReadSector(rootPtr); + errno = imagePlugin.ReadSector(rootPtr, out rootBlockSector); + + if(errno != ErrorNumber.NoError) + continue; rootBlk.type = BigEndianBitConverter.ToUInt32(rootBlockSector, 0x00); AaruConsole.DebugWriteLine("AmigaDOS plugin", "rootBlk.type = {0}", rootBlk.type); @@ -240,7 +261,10 @@ namespace Aaru.Filesystems if(rootPtr + sectorsPerBlock >= partition.End) continue; - rootBlockSector = imagePlugin.ReadSectors(rootPtr, sectorsPerBlock); + errno = imagePlugin.ReadSectors(rootPtr, sectorsPerBlock, out rootBlockSector); + + if(errno != ErrorNumber.NoError) + continue; // Clear checksum on sector rootBlk.checksum = BigEndianBitConverter.ToUInt32(rootBlockSector, 20); @@ -257,8 +281,12 @@ namespace Aaru.Filesystems rootBlk.checksum != rsum) continue; - rootBlockSector = imagePlugin.ReadSectors(rootPtr, sectorsPerBlock); - rootFound = true; + errno = imagePlugin.ReadSectors(rootPtr, sectorsPerBlock, out rootBlockSector); + + if(errno != ErrorNumber.NoError) + continue; + + rootFound = true; break; } diff --git a/Aaru.Filesystems/AppleDOS/Dir.cs b/Aaru.Filesystems/AppleDOS/Dir.cs index 3c81c9eac..6f7a061f0 100644 --- a/Aaru.Filesystems/AppleDOS/Dir.cs +++ b/Aaru.Filesystems/AppleDOS/Dir.cs @@ -35,7 +35,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; using Aaru.CommonTypes.Enums; -using Aaru.CommonTypes.Structs; using Aaru.Helpers; namespace Aaru.Filesystems @@ -93,7 +92,11 @@ namespace Aaru.Filesystems while(lba != 0) { _usedSectors++; - byte[] catSectorB = _device.ReadSector(lba); + ErrorNumber errno = _device.ReadSector(lba, out byte[] catSectorB); + + if(errno != ErrorNumber.NoError) + return errno; + _totalFileEntries += 7; if(_debug) diff --git a/Aaru.Filesystems/AppleDOS/File.cs b/Aaru.Filesystems/AppleDOS/File.cs index eb6e4a83b..c3194a4ae 100644 --- a/Aaru.Filesystems/AppleDOS/File.cs +++ b/Aaru.Filesystems/AppleDOS/File.cs @@ -224,7 +224,10 @@ namespace Aaru.Filesystems while(lba != 0) { _usedSectors++; - byte[] tsSectorB = _device.ReadSector(lba); + ErrorNumber errno = _device.ReadSector(lba, out byte[] tsSectorB); + + if(errno != ErrorNumber.NoError) + return errno; if(_debug) tsListMs.Write(tsSectorB, 0, tsSectorB.Length); @@ -250,7 +253,11 @@ namespace Aaru.Filesystems if(blockLba == 0) break; - byte[] fileBlock = _device.ReadSector(blockLba); + errno = _device.ReadSector(blockLba, out byte[] fileBlock); + + if(errno != ErrorNumber.NoError) + return errno; + fileMs.Write(fileBlock, 0, fileBlock.Length); expectedBlock++; } @@ -287,7 +294,11 @@ namespace Aaru.Filesystems if(!_track2UsedByFiles) tracksOnBoot++; - _bootBlocks = _device.ReadSectors(0, (uint)(tracksOnBoot * _sectorsPerTrack)); + ErrorNumber errno = _device.ReadSectors(0, (uint)(tracksOnBoot * _sectorsPerTrack), out _bootBlocks); + + if(errno != ErrorNumber.NoError) + return errno; + _usedSectors += (uint)(_bootBlocks.Length / _vtoc.bytesPerSector); return ErrorNumber.NoError; diff --git a/Aaru.Filesystems/AppleDOS/Info.cs b/Aaru.Filesystems/AppleDOS/Info.cs index e98cf67ed..9f1eb1fc3 100644 --- a/Aaru.Filesystems/AppleDOS/Info.cs +++ b/Aaru.Filesystems/AppleDOS/Info.cs @@ -32,6 +32,7 @@ using System.Text; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Aaru.Helpers; using Claunia.Encoding; @@ -55,7 +56,11 @@ namespace Aaru.Filesystems int spt = imagePlugin.Info.Sectors == 455 ? 13 : 16; - byte[] vtocB = imagePlugin.ReadSector((ulong)(17 * spt)); + var errno = imagePlugin.ReadSector((ulong)(17 * spt), out byte[] vtocB); + + if(errno != ErrorNumber.NoError) + return false; + _vtoc = Marshal.ByteArrayToStructureLittleEndian(vtocB); return _vtoc.catalogSector < spt && _vtoc.maxTrackSectorPairsPerSector <= 122 && @@ -72,7 +77,11 @@ namespace Aaru.Filesystems int spt = imagePlugin.Info.Sectors == 455 ? 13 : 16; - byte[] vtocB = imagePlugin.ReadSector((ulong)(17 * spt)); + var errno = imagePlugin.ReadSector((ulong)(17 * spt), out byte[] vtocB); + + if(errno != ErrorNumber.NoError) + return; + _vtoc = Marshal.ByteArrayToStructureLittleEndian(vtocB); sb.AppendLine("Apple DOS File System"); diff --git a/Aaru.Filesystems/AppleDOS/Super.cs b/Aaru.Filesystems/AppleDOS/Super.cs index d7a56cb17..701b3f9c4 100644 --- a/Aaru.Filesystems/AppleDOS/Super.cs +++ b/Aaru.Filesystems/AppleDOS/Super.cs @@ -78,14 +78,18 @@ namespace Aaru.Filesystems _sectorsPerTrack = _device.Info.Sectors == 455 ? 13 : 16; // Read the VTOC - _vtocBlocks = _device.ReadSector((ulong)(17 * _sectorsPerTrack)); - _vtoc = Marshal.ByteArrayToStructureLittleEndian(_vtocBlocks); + ErrorNumber error = _device.ReadSector((ulong)(17 * _sectorsPerTrack), out _vtocBlocks); + + if(error != ErrorNumber.NoError) + return error; + + _vtoc = Marshal.ByteArrayToStructureLittleEndian(_vtocBlocks); _track1UsedByFiles = false; _track2UsedByFiles = false; _usedSectors = 1; - ErrorNumber error = ReadCatalog(); + error = ReadCatalog(); if(error != ErrorNumber.NoError) { diff --git a/Aaru.Filesystems/AppleHFS/Info.cs b/Aaru.Filesystems/AppleHFS/Info.cs index 92f4f28e9..f06960d86 100644 --- a/Aaru.Filesystems/AppleHFS/Info.cs +++ b/Aaru.Filesystems/AppleHFS/Info.cs @@ -34,6 +34,7 @@ using System; using System.Linq; using System.Text; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Aaru.Helpers; using Schemas; @@ -50,14 +51,18 @@ namespace Aaru.Filesystems if(2 + partition.Start >= partition.End) return false; - byte[] mdbSector; - ushort drSigWord; + byte[] mdbSector; + ushort drSigWord; + ErrorNumber errno; if(imagePlugin.Info.SectorSize == 2352 || imagePlugin.Info.SectorSize == 2448 || imagePlugin.Info.SectorSize == 2048) { - mdbSector = imagePlugin.ReadSectors(partition.Start, 2); + errno = imagePlugin.ReadSectors(partition.Start, 2, out mdbSector); + + if(errno != ErrorNumber.NoError) + return false; foreach(int offset in new[] { @@ -77,7 +82,10 @@ namespace Aaru.Filesystems } else { - mdbSector = imagePlugin.ReadSector(2 + partition.Start); + errno = imagePlugin.ReadSector(2 + partition.Start, out mdbSector); + + if(errno != ErrorNumber.NoError) + return false; if(mdbSector.Length < 0x7C + 2) return false; @@ -104,9 +112,10 @@ namespace Aaru.Filesystems var sb = new StringBuilder(); - byte[] bbSector = null; - byte[] mdbSector = null; - ushort drSigWord; + byte[] bbSector = null; + byte[] mdbSector = null; + ushort drSigWord; + ErrorNumber errno; bool apmFromHddOnCd = false; @@ -114,7 +123,10 @@ namespace Aaru.Filesystems imagePlugin.Info.SectorSize == 2448 || imagePlugin.Info.SectorSize == 2048) { - byte[] tmpSector = imagePlugin.ReadSectors(partition.Start, 2); + errno = imagePlugin.ReadSectors(partition.Start, 2, out byte[] tmpSector); + + if(errno != ErrorNumber.NoError) + return; foreach(int offset in new[] { @@ -143,11 +155,20 @@ namespace Aaru.Filesystems } else { - mdbSector = imagePlugin.ReadSector(2 + partition.Start); + errno = imagePlugin.ReadSector(2 + partition.Start, out mdbSector); + + if(errno != ErrorNumber.NoError) + return; + drSigWord = BigEndianBitConverter.ToUInt16(mdbSector, 0); if(drSigWord == AppleCommon.HFS_MAGIC) - bbSector = imagePlugin.ReadSector(partition.Start); + { + errno = imagePlugin.ReadSector(partition.Start, out bbSector); + + if(errno != ErrorNumber.NoError) + return; + } else return; } diff --git a/Aaru.Filesystems/AppleHFSPlus.cs b/Aaru.Filesystems/AppleHFSPlus.cs index 9a9e2119c..5765460dc 100644 --- a/Aaru.Filesystems/AppleHFSPlus.cs +++ b/Aaru.Filesystems/AppleHFSPlus.cs @@ -34,6 +34,7 @@ using System; using System.Runtime.InteropServices; using System.Text; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Aaru.Helpers; using Schemas; @@ -53,7 +54,7 @@ namespace Aaru.Filesystems /// public string Name => "Apple HFS+ filesystem"; /// - public Guid Id => new Guid("36405F8D-0D26-6EBE-436F-62F0586B4F08"); + public Guid Id => new("36405F8D-0D26-6EBE-436F-62F0586B4F08"); /// public string Author => "Natalia Portillo"; @@ -70,7 +71,10 @@ namespace Aaru.Filesystems if(0x800 % imagePlugin.Info.SectorSize > 0) sectorsToRead++; - byte[] vhSector = imagePlugin.ReadSectors(partition.Start, sectorsToRead); + ErrorNumber errno = imagePlugin.ReadSectors(partition.Start, sectorsToRead, out byte[] vhSector); + + if(errno != ErrorNumber.NoError) + return false; if(vhSector.Length < 0x800) return false; @@ -98,7 +102,11 @@ namespace Aaru.Filesystems else hfspOffset = 0; - vhSector = imagePlugin.ReadSectors(partition.Start + hfspOffset, sectorsToRead); // Read volume header + errno = imagePlugin.ReadSectors(partition.Start + hfspOffset, sectorsToRead, + out vhSector); // Read volume header + + if(errno != ErrorNumber.NoError) + return false; drSigWord = BigEndianBitConverter.ToUInt16(vhSector, 0x400); @@ -122,7 +130,10 @@ namespace Aaru.Filesystems if(0x800 % imagePlugin.Info.SectorSize > 0) sectorsToRead++; - byte[] vhSector = imagePlugin.ReadSectors(partition.Start, sectorsToRead); + ErrorNumber errno = imagePlugin.ReadSectors(partition.Start, sectorsToRead, out byte[] vhSector); + + if(errno != ErrorNumber.NoError) + return; ushort drSigWord = BigEndianBitConverter.ToUInt16(vhSector, 0x400); @@ -154,7 +165,11 @@ namespace Aaru.Filesystems wrapped = false; } - vhSector = imagePlugin.ReadSectors(partition.Start + hfspOffset, sectorsToRead); // Read volume header + errno = imagePlugin.ReadSectors(partition.Start + hfspOffset, sectorsToRead, + out vhSector); // Read volume header + + if(errno != ErrorNumber.NoError) + return; vh.signature = BigEndianBitConverter.ToUInt16(vhSector, 0x400); diff --git a/Aaru.Filesystems/AppleMFS/File.cs b/Aaru.Filesystems/AppleMFS/File.cs index 96d641b08..10dba2829 100644 --- a/Aaru.Filesystems/AppleMFS/File.cs +++ b/Aaru.Filesystems/AppleMFS/File.cs @@ -351,7 +351,8 @@ namespace Aaru.Filesystems do { - byte[] sectors; + byte[] sectors; + ErrorNumber errno = ErrorNumber.NoError; if(tags) sectors = @@ -359,10 +360,13 @@ namespace Aaru.Filesystems ReadSectorsTag((ulong)((nextBlock - 2) * _sectorsPerBlock) + _volMdb.drAlBlSt + _partitionStart, (uint)_sectorsPerBlock, SectorTagType.AppleSectorTag); else - sectors = + errno = _device. ReadSectors((ulong)((nextBlock - 2) * _sectorsPerBlock) + _volMdb.drAlBlSt + _partitionStart, - (uint)_sectorsPerBlock); + (uint)_sectorsPerBlock, out sectors); + + if(errno != ErrorNumber.NoError) + return errno; ms.Write(sectors, 0, sectors.Length); diff --git a/Aaru.Filesystems/AppleMFS/Info.cs b/Aaru.Filesystems/AppleMFS/Info.cs index 7982da97f..a439a0deb 100644 --- a/Aaru.Filesystems/AppleMFS/Info.cs +++ b/Aaru.Filesystems/AppleMFS/Info.cs @@ -33,6 +33,7 @@ using System; using System.Text; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Aaru.Helpers; using Claunia.Encoding; @@ -50,7 +51,10 @@ namespace Aaru.Filesystems if(2 + partition.Start >= partition.End) return false; - byte[] mdbSector = imagePlugin.ReadSector(2 + partition.Start); + ErrorNumber errno = imagePlugin.ReadSector(2 + partition.Start, out byte[] mdbSector); + + if(errno != ErrorNumber.NoError) + return false; ushort drSigWord = BigEndianBitConverter.ToUInt16(mdbSector, 0x000); @@ -68,8 +72,15 @@ namespace Aaru.Filesystems var mdb = new MasterDirectoryBlock(); - byte[] mdbSector = imagePlugin.ReadSector(2 + partition.Start); - byte[] bbSector = imagePlugin.ReadSector(0 + partition.Start); + ErrorNumber errno = imagePlugin.ReadSector(2 + partition.Start, out byte[] mdbSector); + + if(errno != ErrorNumber.NoError) + return; + + errno = imagePlugin.ReadSector(0 + partition.Start, out byte[] bbSector); + + if(errno != ErrorNumber.NoError) + return; mdb.drSigWord = BigEndianBitConverter.ToUInt16(mdbSector, 0x000); diff --git a/Aaru.Filesystems/AppleMFS/Super.cs b/Aaru.Filesystems/AppleMFS/Super.cs index 1adf471d1..819d0fc21 100644 --- a/Aaru.Filesystems/AppleMFS/Super.cs +++ b/Aaru.Filesystems/AppleMFS/Super.cs @@ -54,6 +54,7 @@ namespace Aaru.Filesystems _device = imagePlugin; _partitionStart = partition.Start; Encoding = encoding ?? Encoding.GetEncoding("macintosh"); + ErrorNumber errno; options ??= GetDefaultOptions(); @@ -62,8 +63,15 @@ namespace Aaru.Filesystems _volMdb = new MasterDirectoryBlock(); - _mdbBlocks = _device.ReadSector(2 + _partitionStart); - _bootBlocks = _device.ReadSector(0 + _partitionStart); + errno = _device.ReadSector(2 + _partitionStart, out _mdbBlocks); + + if(errno != ErrorNumber.NoError) + return errno; + + errno = _device.ReadSector(0 + _partitionStart, out _bootBlocks); + + if(errno != ErrorNumber.NoError) + return errno; _volMdb.drSigWord = BigEndianBitConverter.ToUInt16(_mdbBlocks, 0x000); @@ -87,14 +95,22 @@ namespace Aaru.Filesystems Array.Copy(_mdbBlocks, 0x024, variableSize, 0, _volMdb.drVNSiz + 1); _volMdb.drVN = StringHandlers.PascalToString(variableSize, Encoding); - _directoryBlocks = _device.ReadSectors(_volMdb.drDirSt + _partitionStart, _volMdb.drBlLen); + errno = _device.ReadSectors(_volMdb.drDirSt + _partitionStart, _volMdb.drBlLen, out _directoryBlocks); + + if(errno != ErrorNumber.NoError) + return errno; + int bytesInBlockMap = (_volMdb.drNmAlBlks * 12 / 8) + (_volMdb.drNmAlBlks * 12 % 8); int bytesInWholeMdb = bytesInBlockMap + BYTES_BEFORE_BLOCK_MAP; int sectorsInWholeMdb = (bytesInWholeMdb / (int)_device.Info.SectorSize) + (bytesInWholeMdb % (int)_device.Info.SectorSize); - byte[] wholeMdb = _device.ReadSectors(_partitionStart + 2, (uint)sectorsInWholeMdb); + errno = _device.ReadSectors(_partitionStart + 2, (uint)sectorsInWholeMdb, out byte[] wholeMdb); + + if(errno != ErrorNumber.NoError) + return errno; + _blockMapBytes = new byte[bytesInBlockMap]; Array.Copy(wholeMdb, BYTES_BEFORE_BLOCK_MAP, _blockMapBytes, 0, _blockMapBytes.Length); diff --git a/Aaru.Filesystems/AtheOS.cs b/Aaru.Filesystems/AtheOS.cs index a86e3c3ab..1229953aa 100644 --- a/Aaru.Filesystems/AtheOS.cs +++ b/Aaru.Filesystems/AtheOS.cs @@ -35,6 +35,7 @@ using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; using System.Text; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Aaru.Helpers; using Schemas; @@ -63,7 +64,7 @@ namespace Aaru.Filesystems /// public string Name => "AtheOS Filesystem"; /// - public Guid Id => new Guid("AAB2C4F1-DC07-49EE-A948-576CC51B58C5"); + public Guid Id => new("AAB2C4F1-DC07-49EE-A948-576CC51B58C5"); /// public string Author => "Natalia Portillo"; @@ -80,7 +81,11 @@ namespace Aaru.Filesystems if(sector + partition.Start >= partition.End) return false; - byte[] tmp = imagePlugin.ReadSectors(sector + partition.Start, run); + ErrorNumber errno = imagePlugin.ReadSectors(sector + partition.Start, run, out byte[] tmp); + + if(errno != ErrorNumber.NoError) + return false; + byte[] sbSector = new byte[AFS_SUPERBLOCK_SIZE]; if(offset + AFS_SUPERBLOCK_SIZE > tmp.Length) @@ -109,7 +114,11 @@ namespace Aaru.Filesystems if(imagePlugin.Info.SectorSize < AFS_SUPERBLOCK_SIZE) run = AFS_SUPERBLOCK_SIZE / imagePlugin.Info.SectorSize; - byte[] tmp = imagePlugin.ReadSectors(sector + partition.Start, run); + ErrorNumber errno = imagePlugin.ReadSectors(sector + partition.Start, run, out byte[] tmp); + + if(errno != ErrorNumber.NoError) + return; + byte[] sbSector = new byte[AFS_SUPERBLOCK_SIZE]; Array.Copy(tmp, offset, sbSector, 0, AFS_SUPERBLOCK_SIZE); diff --git a/Aaru.Filesystems/BFS.cs b/Aaru.Filesystems/BFS.cs index 5d93de208..d3037feb6 100644 --- a/Aaru.Filesystems/BFS.cs +++ b/Aaru.Filesystems/BFS.cs @@ -35,6 +35,7 @@ using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; using System.Text; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Aaru.Helpers; using Schemas; @@ -69,7 +70,7 @@ namespace Aaru.Filesystems /// public string Name => "Be Filesystem"; /// - public Guid Id => new Guid("dc8572b3-b6ad-46e4-8de9-cbe123ff6672"); + public Guid Id => new("dc8572b3-b6ad-46e4-8de9-cbe123ff6672"); /// public string Author => "Natalia Portillo"; @@ -79,7 +80,10 @@ namespace Aaru.Filesystems if(2 + partition.Start >= partition.End) return false; - byte[] sbSector = imagePlugin.ReadSector(0 + partition.Start); + ErrorNumber errno = imagePlugin.ReadSector(0 + partition.Start, out byte[] sbSector); + + if(errno != ErrorNumber.NoError) + return false; uint magic = BitConverter.ToUInt32(sbSector, 0x20); uint magicBe = BigEndianBitConverter.ToUInt32(sbSector, 0x20); @@ -98,7 +102,10 @@ namespace Aaru.Filesystems magicBe == BEFS_MAGIC1) return true; - sbSector = imagePlugin.ReadSector(1 + partition.Start); + errno = imagePlugin.ReadSector(1 + partition.Start, out sbSector); + + if(errno != ErrorNumber.NoError) + return false; magic = BitConverter.ToUInt32(sbSector, 0x20); magicBe = BigEndianBitConverter.ToUInt32(sbSector, 0x20); @@ -117,7 +124,10 @@ namespace Aaru.Filesystems var besb = new SuperBlock(); - byte[] sbSector = imagePlugin.ReadSector(0 + partition.Start); + ErrorNumber errno = imagePlugin.ReadSector(0 + partition.Start, out byte[] sbSector); + + if(errno != ErrorNumber.NoError) + return; bool littleEndian; @@ -128,7 +138,11 @@ namespace Aaru.Filesystems littleEndian = besb.magic1 == BEFS_CIGAM1; else { - sbSector = imagePlugin.ReadSector(1 + partition.Start); + errno = imagePlugin.ReadSector(1 + partition.Start, out sbSector); + + if(errno != ErrorNumber.NoError) + return; + besb.magic1 = BigEndianBitConverter.ToUInt32(sbSector, 0x20); if(besb.magic1 == BEFS_MAGIC1 || @@ -136,7 +150,11 @@ namespace Aaru.Filesystems littleEndian = besb.magic1 == BEFS_CIGAM1; else if(sbSector.Length >= 0x400) { - byte[] temp = imagePlugin.ReadSector(0 + partition.Start); + errno = imagePlugin.ReadSector(0 + partition.Start, out byte[] temp); + + if(errno != ErrorNumber.NoError) + return; + besb.magic1 = BigEndianBitConverter.ToUInt32(temp, 0x220); if(besb.magic1 == BEFS_MAGIC1 || diff --git a/Aaru.Filesystems/BTRFS.cs b/Aaru.Filesystems/BTRFS.cs index 73e18c747..d8a709eed 100644 --- a/Aaru.Filesystems/BTRFS.cs +++ b/Aaru.Filesystems/BTRFS.cs @@ -34,6 +34,7 @@ using System; using System.Runtime.InteropServices; using System.Text; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Aaru.Console; using Schemas; @@ -55,7 +56,7 @@ namespace Aaru.Filesystems /// public string Name => "B-tree file system"; /// - public Guid Id => new Guid("C904CF15-5222-446B-B7DB-02EAC5D781B3"); + public Guid Id => new("C904CF15-5222-446B-B7DB-02EAC5D781B3"); /// public string Author => "Natalia Portillo"; @@ -71,7 +72,11 @@ namespace Aaru.Filesystems if(sbSectorOff + partition.Start >= partition.End) return false; - byte[] sector = imagePlugin.ReadSectors(sbSectorOff + partition.Start, sbSectorSize); + ErrorNumber errno = imagePlugin.ReadSectors(sbSectorOff + partition.Start, sbSectorSize, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return false; + SuperBlock btrfsSb; try @@ -103,7 +108,10 @@ namespace Aaru.Filesystems ulong sbSectorOff = 0x10000 / imagePlugin.Info.SectorSize; uint sbSectorSize = 0x1000 / imagePlugin.Info.SectorSize; - byte[] sector = imagePlugin.ReadSectors(sbSectorOff + partition.Start, sbSectorSize); + ErrorNumber errno = imagePlugin.ReadSectors(sbSectorOff + partition.Start, sbSectorSize, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return; SuperBlock btrfsSb = Marshal.ByteArrayToStructureLittleEndian(sector); diff --git a/Aaru.Filesystems/CBM.cs b/Aaru.Filesystems/CBM.cs index bee3159ed..10bb32a60 100644 --- a/Aaru.Filesystems/CBM.cs +++ b/Aaru.Filesystems/CBM.cs @@ -34,6 +34,7 @@ using System; using System.Runtime.InteropServices; using System.Text; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Aaru.Helpers; using Claunia.Encoding; @@ -52,7 +53,7 @@ namespace Aaru.Filesystems /// public string Name => "Commodore file system"; /// - public Guid Id => new Guid("D104744E-A376-450C-BAC0-1347C93F983B"); + public Guid Id => new("D104744E-A376-450C-BAC0-1347C93F983B"); /// public Encoding Encoding { get; private set; } /// @@ -77,7 +78,11 @@ namespace Aaru.Filesystems if(imagePlugin.Info.Sectors == 3200) { - sector = imagePlugin.ReadSector(1560); + ErrorNumber errno = imagePlugin.ReadSector(1560, out sector); + + if(errno != ErrorNumber.NoError) + return false; + Header cbmHdr = Marshal.ByteArrayToStructureLittleEndian
(sector); if(cbmHdr.diskDosVersion == 0x44 && @@ -87,7 +92,11 @@ namespace Aaru.Filesystems } else { - sector = imagePlugin.ReadSector(357); + ErrorNumber errno = imagePlugin.ReadSector(357, out sector); + + if(errno != ErrorNumber.NoError) + return false; + BAM cbmBam = Marshal.ByteArrayToStructureLittleEndian(sector); if(cbmBam.dosVersion == 0x41 && @@ -104,7 +113,8 @@ namespace Aaru.Filesystems public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information, Encoding encoding) { - Encoding = new PETSCII(); + Encoding = new PETSCII(); + information = ""; byte[] sector; var sbInformation = new StringBuilder(); @@ -120,7 +130,11 @@ namespace Aaru.Filesystems if(imagePlugin.Info.Sectors == 3200) { - sector = imagePlugin.ReadSector(1560); + ErrorNumber errno = imagePlugin.ReadSector(1560, out sector); + + if(errno != ErrorNumber.NoError) + return; + Header cbmHdr = Marshal.ByteArrayToStructureLittleEndian
(sector); sbInformation.AppendFormat("Directory starts at track {0} sector {1}", cbmHdr.directoryTrack, @@ -151,7 +165,11 @@ namespace Aaru.Filesystems } else { - sector = imagePlugin.ReadSector(357); + ErrorNumber errno = imagePlugin.ReadSector(357, out sector); + + if(errno != ErrorNumber.NoError) + return; + BAM cbmBam = Marshal.ByteArrayToStructureLittleEndian(sector); sbInformation.AppendFormat("Directory starts at track {0} sector {1}", cbmBam.directoryTrack, diff --git a/Aaru.Filesystems/CPM/Info.cs b/Aaru.Filesystems/CPM/Info.cs index 0dcf0a6f8..318d7c4df 100644 --- a/Aaru.Filesystems/CPM/Info.cs +++ b/Aaru.Filesystems/CPM/Info.cs @@ -35,6 +35,7 @@ using System.IO; using System.Linq; using System.Text; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Aaru.Console; using Aaru.Helpers; @@ -47,6 +48,8 @@ namespace Aaru.Filesystems /// public bool Identify(IMediaImage imagePlugin, Partition partition) { + ErrorNumber errno = ErrorNumber.NoError; + // This will only continue on devices with a chance to have ever been used by CP/M while failing on all others // It's ugly, but will stop a lot of false positives switch(imagePlugin.Info.MediaType) @@ -170,139 +173,143 @@ namespace Aaru.Filesystems if(!_cpmFound) { // Read CHS = {0,0,1} - sector = imagePlugin.ReadSector(0 + partition.Start); - int amsSbOffset = 0; + errno = imagePlugin.ReadSector(0 + partition.Start, out sector); - uint sig1 = BitConverter.ToUInt32(sector, 0x2B); - uint sig2 = BitConverter.ToUInt32(sector, 0x33) & 0x00FFFFFF; - uint sig3 = BitConverter.ToUInt32(sector, 0x7C); - - // PCW16 extended boot record - if(sig1 == 0x4D2F5043 && - sig2 == 0x004B5344 && - sig3 == sig1) - amsSbOffset = 0x80; - - // Read the superblock - AmstradSuperBlock amsSb = - Marshal.ByteArrayToStructureLittleEndian(sector, amsSbOffset, 16); - - // Check that format byte and sidedness indicate the same number of sizes - if((amsSb.format == 0 && (amsSb.sidedness & 0x02) == 0) || - (amsSb.format == 2 && (amsSb.sidedness & 0x02) == 1) || - (amsSb.format == 2 && (amsSb.sidedness & 0x02) == 2)) + if(errno == ErrorNumber.NoError) { - // Calculate device limits - ulong sides = (ulong)(amsSb.format == 0 ? 1 : 2); - ulong sectorCount = (ulong)(amsSb.tps * amsSb.spt * (byte)sides); - sectorSize = (ulong)(128 << amsSb.psh); + int amsSbOffset = 0; - // Compare device limits from superblock to real limits - if(sectorSize == imagePlugin.Info.SectorSize && - sectorCount == imagePlugin.Info.Sectors) + uint sig1 = BitConverter.ToUInt32(sector, 0x2B); + uint sig2 = BitConverter.ToUInt32(sector, 0x33) & 0x00FFFFFF; + uint sig3 = BitConverter.ToUInt32(sector, 0x7C); + + // PCW16 extended boot record + if(sig1 == 0x4D2F5043 && + sig2 == 0x004B5344 && + sig3 == sig1) + amsSbOffset = 0x80; + + // Read the superblock + AmstradSuperBlock amsSb = + Marshal.ByteArrayToStructureLittleEndian(sector, amsSbOffset, 16); + + // Check that format byte and sidedness indicate the same number of sizes + if((amsSb.format == 0 && (amsSb.sidedness & 0x02) == 0) || + (amsSb.format == 2 && (amsSb.sidedness & 0x02) == 1) || + (amsSb.format == 2 && (amsSb.sidedness & 0x02) == 2)) { - _cpmFound = true; - firstDirectorySector = (ulong)(amsSb.off * amsSb.spt); + // Calculate device limits + ulong sides = (ulong)(amsSb.format == 0 ? 1 : 2); + ulong sectorCount = (ulong)(amsSb.tps * amsSb.spt * (byte)sides); + sectorSize = (ulong)(128 << amsSb.psh); - // Build a DiscParameterBlock - _dpb = new DiscParameterBlock + // Compare device limits from superblock to real limits + if(sectorSize == imagePlugin.Info.SectorSize && + sectorCount == imagePlugin.Info.Sectors) { - al0 = sectorCount == 1440 ? (byte)0xF0 : (byte)0xC0, - spt = amsSb.spt, - bsh = amsSb.bsh - }; + _cpmFound = true; + firstDirectorySector = (ulong)(amsSb.off * amsSb.spt); - for(int i = 0; i < _dpb.bsh; i++) - _dpb.blm += (byte)Math.Pow(2, i); - - if(sectorCount >= 1440) - { - _dpb.cks = 0x40; - _dpb.drm = 0xFF; - } - else - { - _dpb.cks = 0x10; - _dpb.drm = 0x3F; - } - - _dpb.dsm = 0; // I don't care - _dpb.exm = sectorCount == 2880 ? (byte)1 : (byte)0; - _dpb.off = amsSb.off; - _dpb.psh = amsSb.psh; - - for(int i = 0; i < _dpb.psh; i++) - _dpb.phm += (byte)Math.Pow(2, i); - - _dpb.spt = (ushort)(amsSb.spt * (sectorSize / 128)); - uint directoryLength = (uint)(((ulong)_dpb.drm + 1) * 32 / sectorSize); - - directory = imagePlugin.ReadSectors(firstDirectorySector + partition.Start, - directoryLength); - - // Build a CP/M disk definition - _workingDefinition = new CpmDefinition - { - al0 = _dpb.al0, - al1 = _dpb.al1, - bitrate = "LOW", - blm = _dpb.blm, - bsh = _dpb.bsh, - bytesPerSector = 512, - cylinders = amsSb.tps, - drm = _dpb.drm, - dsm = _dpb.dsm, - encoding = "MFM", - evenOdd = false, - exm = _dpb.exm, - label = null, - comment = "Amstrad PCW superblock", - ofs = _dpb.off, - sectorsPerTrack = amsSb.spt, - side1 = new Side + // Build a DiscParameterBlock + _dpb = new DiscParameterBlock { - sideId = 0, - sectorIds = new int[amsSb.spt] + al0 = sectorCount == 1440 ? (byte)0xF0 : (byte)0xC0, + spt = amsSb.spt, + bsh = amsSb.bsh + }; + + for(int i = 0; i < _dpb.bsh; i++) + _dpb.blm += (byte)Math.Pow(2, i); + + if(sectorCount >= 1440) + { + _dpb.cks = 0x40; + _dpb.drm = 0xFF; } - }; - - for(int si = 0; si < amsSb.spt; si++) - _workingDefinition.side1.sectorIds[si] = si + 1; - - if(amsSb.format == 2) - { - switch(amsSb.sidedness & 0x02) + else { - case 1: - _workingDefinition.order = "SIDES"; - - break; - case 2: - _workingDefinition.order = "CYLINDERS"; - - break; - default: - _workingDefinition.order = null; - - break; + _dpb.cks = 0x10; + _dpb.drm = 0x3F; } - _workingDefinition.side2 = new Side + _dpb.dsm = 0; // I don't care + _dpb.exm = sectorCount == 2880 ? (byte)1 : (byte)0; + _dpb.off = amsSb.off; + _dpb.psh = amsSb.psh; + + for(int i = 0; i < _dpb.psh; i++) + _dpb.phm += (byte)Math.Pow(2, i); + + _dpb.spt = (ushort)(amsSb.spt * (sectorSize / 128)); + uint directoryLength = (uint)(((ulong)_dpb.drm + 1) * 32 / sectorSize); + + errno = imagePlugin.ReadSectors(firstDirectorySector + partition.Start, directoryLength, + out directory); + + // Build a CP/M disk definition + _workingDefinition = new CpmDefinition { - sideId = 1, - sectorIds = new int[amsSb.spt] + al0 = _dpb.al0, + al1 = _dpb.al1, + bitrate = "LOW", + blm = _dpb.blm, + bsh = _dpb.bsh, + bytesPerSector = 512, + cylinders = amsSb.tps, + drm = _dpb.drm, + dsm = _dpb.dsm, + encoding = "MFM", + evenOdd = false, + exm = _dpb.exm, + label = null, + comment = "Amstrad PCW superblock", + ofs = _dpb.off, + sectorsPerTrack = amsSb.spt, + side1 = new Side + { + sideId = 0, + sectorIds = new int[amsSb.spt] + } }; for(int si = 0; si < amsSb.spt; si++) - _workingDefinition.side2.sectorIds[si] = si + 1; + _workingDefinition.side1.sectorIds[si] = si + 1; + + if(amsSb.format == 2) + { + switch(amsSb.sidedness & 0x02) + { + case 1: + _workingDefinition.order = "SIDES"; + + break; + case 2: + _workingDefinition.order = "CYLINDERS"; + + break; + default: + _workingDefinition.order = null; + + break; + } + + _workingDefinition.side2 = new Side + { + sideId = 1, + sectorIds = new int[amsSb.spt] + }; + + for(int si = 0; si < amsSb.spt; si++) + _workingDefinition.side2.sectorIds[si] = si + 1; + } + else + _workingDefinition.order = null; + + _workingDefinition.skew = 2; + _workingDefinition.sofs = 0; + + AaruConsole.DebugWriteLine("CP/M Plugin", "Found Amstrad superblock."); } - else - _workingDefinition.order = null; - - _workingDefinition.skew = 2; - _workingDefinition.sofs = 0; - - AaruConsole.DebugWriteLine("CP/M Plugin", "Found Amstrad superblock."); } } } @@ -311,470 +318,68 @@ namespace Aaru.Filesystems if(!_cpmFound) { // Read CHS = {0,0,4} - sector = imagePlugin.ReadSector(3 + partition.Start); - ushort sum = 0; + errno = imagePlugin.ReadSector(3 + partition.Start, out sector); - // Sum of all 16-bit words that make this sector must be 0 - for(int i = 0; i < sector.Length; i += 2) - sum += BitConverter.ToUInt16(sector, i); - - // It may happen that there is a corrupted superblock - // Better to ignore corrupted than to false positive the rest - if(sum == 0) + if(errno == ErrorNumber.NoError) { - // Read the superblock - HardDiskSuperBlock hddSb = Marshal.ByteArrayToStructureLittleEndian(sector); + ushort sum = 0; - // Calculate volume size - sectorSize = (ulong)(hddSb.recordsPerSector * 128); - ulong sectorsInPartition = (ulong)(hddSb.cylinders * hddSb.heads * hddSb.sectorsPerTrack); + // Sum of all 16-bit words that make this sector must be 0 + for(int i = 0; i < sector.Length; i += 2) + sum += BitConverter.ToUInt16(sector, i); - ulong startingSector = - (ulong)(((hddSb.firstCylinder * hddSb.heads) + hddSb.heads) * hddSb.sectorsPerTrack); - - // If volume size corresponds with working partition (this variant will be inside MBR partitioning) - if(sectorSize == imagePlugin.Info.SectorSize && - startingSector == partition.Start && - sectorsInPartition + partition.Start <= partition.End) + // It may happen that there is a corrupted superblock + // Better to ignore corrupted than to false positive the rest + if(sum == 0) { - _cpmFound = true; - firstDirectorySector = (ulong)(hddSb.off * hddSb.sectorsPerTrack); + // Read the superblock + HardDiskSuperBlock hddSb = + Marshal.ByteArrayToStructureLittleEndian(sector); - // Build a DiscParameterBlock - _dpb = new DiscParameterBlock + // Calculate volume size + sectorSize = (ulong)(hddSb.recordsPerSector * 128); + ulong sectorsInPartition = (ulong)(hddSb.cylinders * hddSb.heads * hddSb.sectorsPerTrack); + + ulong startingSector = + (ulong)(((hddSb.firstCylinder * hddSb.heads) + hddSb.heads) * hddSb.sectorsPerTrack); + + // If volume size corresponds with working partition (this variant will be inside MBR partitioning) + if(sectorSize == imagePlugin.Info.SectorSize && + startingSector == partition.Start && + sectorsInPartition + partition.Start <= partition.End) { - al0 = (byte)hddSb.al0, - al1 = (byte)hddSb.al1, - blm = hddSb.blm, - bsh = hddSb.bsh, - cks = hddSb.cks, - drm = hddSb.drm, - dsm = hddSb.dsm, - exm = hddSb.exm, - off = hddSb.off, - - // Needed? - phm = 0, - - // Needed? - psh = 0, - spt = hddSb.spt - }; - - uint directoryLength = (uint)(((ulong)_dpb.drm + 1) * 32 / sectorSize); - - directory = imagePlugin.ReadSectors(firstDirectorySector + partition.Start, - directoryLength); - - AaruConsole.DebugWriteLine("CP/M Plugin", "Found CP/M-86 hard disk superblock."); - - // Build a CP/M disk definition - _workingDefinition = new CpmDefinition - { - al0 = _dpb.al0, - al1 = _dpb.al1, - bitrate = "HIGH", - blm = _dpb.blm, - bsh = _dpb.bsh, - bytesPerSector = 512, - cylinders = hddSb.cylinders, - drm = _dpb.drm, - dsm = _dpb.dsm, - encoding = "MFM", - evenOdd = false, - exm = _dpb.exm, - label = null, - comment = "CP/M-86 hard disk superblock", - ofs = _dpb.off, - sectorsPerTrack = hddSb.sectorsPerTrack, - side1 = new Side - { - sideId = 0, - sectorIds = new int[hddSb.sectorsPerTrack] - }, - order = "SIDES", - side2 = new Side - { - sideId = 1, - sectorIds = new int[hddSb.sectorsPerTrack] - }, - skew = 0, - sofs = 0 - }; - - for(int si = 0; si < hddSb.sectorsPerTrack; si++) - _workingDefinition.side1.sectorIds[si] = si + 1; - - for(int si = 0; si < hddSb.spt; si++) - _workingDefinition.side2.sectorIds[si] = si + 1; - } - } - } - - // Try CP/M-86 format ID for floppies - if(!_cpmFound) - { - // Read CHS = {0,0,1} - sector = imagePlugin.ReadSector(0 + partition.Start); - byte formatByte; - - // Check for alternate location of format ID - if(sector.Last() == 0x00 || - sector.Last() == 0xFF) - if(sector[0x40] == 0x94 || - sector[0x40] == 0x26) - formatByte = sector[0x40]; - else - formatByte = sector.Last(); - else - formatByte = sector.Last(); - - uint firstDirectorySector86 = 0; - - // Check format ID - // If it is one of the known IDs, check disk size corresponds to the one we expect - // If so, build a DiscParameterBlock and a CP/M disk definition - // Will not work on over-formatted disks (40 cylinder volume on an 80 cylinder disk, - // something that happens a lot in IBM PC 5.25" disks) - switch((FormatByte)formatByte) - { - case FormatByte.k160: - if(imagePlugin.Info.SectorSize == 512 && - imagePlugin.Info.Sectors == 320) - { - _cpmFound = true; - firstDirectorySector86 = 8; + _cpmFound = true; + firstDirectorySector = (ulong)(hddSb.off * hddSb.sectorsPerTrack); + // Build a DiscParameterBlock _dpb = new DiscParameterBlock { - al0 = 0xC0, - al1 = 0, - blm = 7, - bsh = 3, - cks = 0x10, - drm = 0x3F, - dsm = 0x9B, - exm = 0, - off = 1, - phm = 3, - psh = 2, - spt = 8 * 4 + al0 = (byte)hddSb.al0, + al1 = (byte)hddSb.al1, + blm = hddSb.blm, + bsh = hddSb.bsh, + cks = hddSb.cks, + drm = hddSb.drm, + dsm = hddSb.dsm, + exm = hddSb.exm, + off = hddSb.off, + + // Needed? + phm = 0, + + // Needed? + psh = 0, + spt = hddSb.spt }; - _workingDefinition = new CpmDefinition - { - al0 = _dpb.al0, - al1 = _dpb.al1, - bitrate = "LOW", - blm = _dpb.blm, - bsh = _dpb.bsh, - bytesPerSector = 512, - cylinders = 40, - drm = _dpb.drm, - dsm = _dpb.dsm, - encoding = "MFM", - evenOdd = false, - exm = _dpb.exm, - label = null, - comment = "CP/M-86 floppy identifier", - ofs = _dpb.off, - sectorsPerTrack = 8, - side1 = new Side - { - sideId = 0, - sectorIds = new int[8] - }, - skew = 0, - sofs = 0 - }; + uint directoryLength = (uint)(((ulong)_dpb.drm + 1) * 32 / sectorSize); - for(int si = 0; si < 8; si++) - _workingDefinition.side1.sectorIds[si] = si + 1; - } + errno = imagePlugin.ReadSectors(firstDirectorySector + partition.Start, directoryLength, + out directory); - break; - case FormatByte.k320: - if(imagePlugin.Info.SectorSize == 512 && - imagePlugin.Info.Sectors == 640) - { - _cpmFound = true; - firstDirectorySector86 = 16; - - _dpb = new DiscParameterBlock - { - al0 = 0x80, - al1 = 0, - blm = 0x0F, - bsh = 4, - cks = 0x10, - drm = 0x3F, - dsm = 0x9D, - exm = 1, - off = 2, - phm = 3, - psh = 2, - spt = 8 * 4 - }; - - _workingDefinition = new CpmDefinition - { - al0 = _dpb.al0, - al1 = _dpb.al1, - bitrate = "LOW", - blm = _dpb.blm, - bsh = _dpb.bsh, - bytesPerSector = 512, - cylinders = 40, - drm = _dpb.drm, - dsm = _dpb.dsm, - encoding = "MFM", - evenOdd = false, - exm = _dpb.exm, - label = null, - comment = "CP/M-86 floppy identifier", - ofs = _dpb.off, - sectorsPerTrack = 8, - side1 = new Side - { - sideId = 0, - sectorIds = new int[8] - }, - order = "SIDES", - side2 = new Side - { - sideId = 1, - sectorIds = new int[8] - }, - skew = 0, - sofs = 0 - }; - - for(int si = 0; si < 8; si++) - _workingDefinition.side1.sectorIds[si] = si + 1; - - for(int si = 0; si < 8; si++) - _workingDefinition.side2.sectorIds[si] = si + 1; - } - - break; - case FormatByte.k360: - case FormatByte.k360Alt: - case FormatByte.k360Alt2: - if(imagePlugin.Info.SectorSize == 512 && - imagePlugin.Info.Sectors == 720) - { - _cpmFound = true; - firstDirectorySector86 = 36; - - _dpb = new DiscParameterBlock - { - al0 = 0x80, - al1 = 0, - blm = 0x0F, - bsh = 4, - cks = 0x10, - drm = 0x3F, - dsm = 0, // Unknown. Needed? - exm = 1, - off = 4, - phm = 3, - psh = 2, - spt = 9 * 4 - }; - - _workingDefinition = new CpmDefinition - { - al0 = _dpb.al0, - al1 = _dpb.al1, - bitrate = "LOW", - blm = _dpb.blm, - bsh = _dpb.bsh, - bytesPerSector = 512, - cylinders = 40, - drm = _dpb.drm, - dsm = _dpb.dsm, - encoding = "MFM", - evenOdd = false, - exm = _dpb.exm, - label = null, - comment = "CP/M-86 floppy identifier", - ofs = _dpb.off, - sectorsPerTrack = 9, - side1 = new Side - { - sideId = 0, - sectorIds = new int[9] - }, - order = "SIDES", - side2 = new Side - { - sideId = 1, - sectorIds = new int[9] - }, - skew = 0, - sofs = 0 - }; - - for(int si = 0; si < 9; si++) - _workingDefinition.side1.sectorIds[si] = si + 1; - - for(int si = 0; si < 9; si++) - _workingDefinition.side2.sectorIds[si] = si + 1; - } - - break; - case FormatByte.k720: - case FormatByte.k720Alt: - if(imagePlugin.Info.SectorSize == 512 && - imagePlugin.Info.Sectors == 1440) - { - _cpmFound = true; - firstDirectorySector86 = 36; - - _dpb = new DiscParameterBlock - { - al0 = 0xF0, - al1 = 0, - blm = 0x0F, - bsh = 4, - cks = 0x40, - drm = 0xFF, - dsm = 0x15E, - exm = 0, - off = 4, - phm = 3, - psh = 2, - spt = 9 * 4 - }; - - _workingDefinition = new CpmDefinition - { - al0 = _dpb.al0, - al1 = _dpb.al1, - bitrate = "LOW", - blm = _dpb.blm, - bsh = _dpb.bsh, - bytesPerSector = 512, - cylinders = 80, - drm = _dpb.drm, - dsm = _dpb.dsm, - encoding = "MFM", - evenOdd = false, - exm = _dpb.exm, - label = null, - comment = "CP/M-86 floppy identifier", - ofs = _dpb.off, - sectorsPerTrack = 9, - side1 = new Side - { - sideId = 0, - sectorIds = new int[9] - }, - order = "SIDES", - side2 = new Side - { - sideId = 1, - sectorIds = new int[9] - }, - skew = 0, - sofs = 0 - }; - - for(int si = 0; si < 9; si++) - _workingDefinition.side1.sectorIds[si] = si + 1; - - for(int si = 0; si < 9; si++) - _workingDefinition.side2.sectorIds[si] = si + 1; - } - - break; - case FormatByte.f720: - if(imagePlugin.Info.SectorSize == 512 && - imagePlugin.Info.Sectors == 1440) - { - _cpmFound = true; - firstDirectorySector86 = 18; - - _dpb = new DiscParameterBlock - { - al0 = 0xF0, - al1 = 0, - blm = 0x0F, - bsh = 4, - cks = 0x40, - drm = 0xFF, - dsm = 0x162, - exm = 0, - off = 2, - phm = 3, - psh = 2, - spt = 9 * 4 - }; - - _workingDefinition = new CpmDefinition - { - al0 = _dpb.al0, - al1 = _dpb.al1, - bitrate = "LOW", - blm = _dpb.blm, - bsh = _dpb.bsh, - bytesPerSector = 512, - cylinders = 80, - drm = _dpb.drm, - dsm = _dpb.dsm, - encoding = "MFM", - evenOdd = false, - exm = _dpb.exm, - label = null, - comment = "CP/M-86 floppy identifier", - ofs = _dpb.off, - sectorsPerTrack = 9, - side1 = new Side - { - sideId = 0, - sectorIds = new int[9] - }, - order = "CYLINDERS", - side2 = new Side - { - sideId = 1, - sectorIds = new int[9] - }, - skew = 0, - sofs = 0 - }; - - for(int si = 0; si < 9; si++) - _workingDefinition.side1.sectorIds[si] = si + 1; - - for(int si = 0; si < 9; si++) - _workingDefinition.side2.sectorIds[si] = si + 1; - } - - break; - case FormatByte.f1200: - if(imagePlugin.Info.SectorSize == 512 && - imagePlugin.Info.Sectors == 2400) - { - _cpmFound = true; - firstDirectorySector86 = 30; - - _dpb = new DiscParameterBlock - { - al0 = 0xC0, - al1 = 0, - blm = 0x1F, - bsh = 5, - cks = 0x40, - drm = 0xFF, - dsm = 0x127, - exm = 1, - off = 2, - phm = 3, - psh = 2, - spt = 15 * 4 - }; + AaruConsole.DebugWriteLine("CP/M Plugin", "Found CP/M-86 hard disk superblock."); + // Build a CP/M disk definition _workingDefinition = new CpmDefinition { al0 = _dpb.al0, @@ -783,110 +388,524 @@ namespace Aaru.Filesystems blm = _dpb.blm, bsh = _dpb.bsh, bytesPerSector = 512, - cylinders = 80, + cylinders = hddSb.cylinders, drm = _dpb.drm, dsm = _dpb.dsm, encoding = "MFM", evenOdd = false, exm = _dpb.exm, label = null, - comment = "CP/M-86 floppy identifier", + comment = "CP/M-86 hard disk superblock", ofs = _dpb.off, - sectorsPerTrack = 15, + sectorsPerTrack = hddSb.sectorsPerTrack, side1 = new Side { sideId = 0, - sectorIds = new int[15] + sectorIds = new int[hddSb.sectorsPerTrack] }, - order = "CYLINDERS", + order = "SIDES", side2 = new Side { sideId = 1, - sectorIds = new int[15] + sectorIds = new int[hddSb.sectorsPerTrack] }, skew = 0, sofs = 0 }; - for(int si = 0; si < 15; si++) + for(int si = 0; si < hddSb.sectorsPerTrack; si++) _workingDefinition.side1.sectorIds[si] = si + 1; - for(int si = 0; si < 15; si++) + for(int si = 0; si < hddSb.spt; si++) _workingDefinition.side2.sectorIds[si] = si + 1; } - - break; - case FormatByte.f1440: - if(imagePlugin.Info.SectorSize == 512 && - imagePlugin.Info.Sectors == 2880) - { - _cpmFound = true; - firstDirectorySector86 = 36; - - _dpb = new DiscParameterBlock - { - al0 = 0xC0, - al1 = 0, - blm = 0x1F, - bsh = 5, - cks = 0x40, - drm = 0xFF, - dsm = 0x162, - exm = 1, - off = 2, - phm = 3, - psh = 2, - spt = 18 * 4 - }; - - _workingDefinition = new CpmDefinition - { - al0 = _dpb.al0, - al1 = _dpb.al1, - bitrate = "LOW", - blm = _dpb.blm, - bsh = _dpb.bsh, - bytesPerSector = 512, - cylinders = 80, - drm = _dpb.drm, - dsm = _dpb.dsm, - encoding = "MFM", - evenOdd = false, - exm = _dpb.exm, - label = null, - comment = "CP/M-86 floppy identifier", - ofs = _dpb.off, - sectorsPerTrack = 18, - side1 = new Side - { - sideId = 0, - sectorIds = new int[18] - }, - order = "CYLINDERS", - side2 = new Side - { - sideId = 1, - sectorIds = new int[18] - }, - skew = 0, - sofs = 0 - }; - - for(int si = 0; si < 18; si++) - _workingDefinition.side1.sectorIds[si] = si + 1; - - for(int si = 0; si < 18; si++) - _workingDefinition.side2.sectorIds[si] = si + 1; - } - - break; + } } + } - if(_cpmFound) + // Try CP/M-86 format ID for floppies + if(!_cpmFound) + { + // Read CHS = {0,0,1} + errno = imagePlugin.ReadSector(0 + partition.Start, out sector); + + if(errno == ErrorNumber.NoError) { - uint directoryLength = (uint)(((ulong)_dpb.drm + 1) * 32 / imagePlugin.Info.SectorSize); - directory = imagePlugin.ReadSectors(firstDirectorySector86 + partition.Start, directoryLength); - AaruConsole.DebugWriteLine("CP/M Plugin", "Found CP/M-86 floppy identifier."); + byte formatByte; + + // Check for alternate location of format ID + if(sector.Last() == 0x00 || + sector.Last() == 0xFF) + if(sector[0x40] == 0x94 || + sector[0x40] == 0x26) + formatByte = sector[0x40]; + else + formatByte = sector.Last(); + else + formatByte = sector.Last(); + + uint firstDirectorySector86 = 0; + + // Check format ID + // If it is one of the known IDs, check disk size corresponds to the one we expect + // If so, build a DiscParameterBlock and a CP/M disk definition + // Will not work on over-formatted disks (40 cylinder volume on an 80 cylinder disk, + // something that happens a lot in IBM PC 5.25" disks) + switch((FormatByte)formatByte) + { + case FormatByte.k160: + if(imagePlugin.Info.SectorSize == 512 && + imagePlugin.Info.Sectors == 320) + { + _cpmFound = true; + firstDirectorySector86 = 8; + + _dpb = new DiscParameterBlock + { + al0 = 0xC0, + al1 = 0, + blm = 7, + bsh = 3, + cks = 0x10, + drm = 0x3F, + dsm = 0x9B, + exm = 0, + off = 1, + phm = 3, + psh = 2, + spt = 8 * 4 + }; + + _workingDefinition = new CpmDefinition + { + al0 = _dpb.al0, + al1 = _dpb.al1, + bitrate = "LOW", + blm = _dpb.blm, + bsh = _dpb.bsh, + bytesPerSector = 512, + cylinders = 40, + drm = _dpb.drm, + dsm = _dpb.dsm, + encoding = "MFM", + evenOdd = false, + exm = _dpb.exm, + label = null, + comment = "CP/M-86 floppy identifier", + ofs = _dpb.off, + sectorsPerTrack = 8, + side1 = new Side + { + sideId = 0, + sectorIds = new int[8] + }, + skew = 0, + sofs = 0 + }; + + for(int si = 0; si < 8; si++) + _workingDefinition.side1.sectorIds[si] = si + 1; + } + + break; + case FormatByte.k320: + if(imagePlugin.Info.SectorSize == 512 && + imagePlugin.Info.Sectors == 640) + { + _cpmFound = true; + firstDirectorySector86 = 16; + + _dpb = new DiscParameterBlock + { + al0 = 0x80, + al1 = 0, + blm = 0x0F, + bsh = 4, + cks = 0x10, + drm = 0x3F, + dsm = 0x9D, + exm = 1, + off = 2, + phm = 3, + psh = 2, + spt = 8 * 4 + }; + + _workingDefinition = new CpmDefinition + { + al0 = _dpb.al0, + al1 = _dpb.al1, + bitrate = "LOW", + blm = _dpb.blm, + bsh = _dpb.bsh, + bytesPerSector = 512, + cylinders = 40, + drm = _dpb.drm, + dsm = _dpb.dsm, + encoding = "MFM", + evenOdd = false, + exm = _dpb.exm, + label = null, + comment = "CP/M-86 floppy identifier", + ofs = _dpb.off, + sectorsPerTrack = 8, + side1 = new Side + { + sideId = 0, + sectorIds = new int[8] + }, + order = "SIDES", + side2 = new Side + { + sideId = 1, + sectorIds = new int[8] + }, + skew = 0, + sofs = 0 + }; + + for(int si = 0; si < 8; si++) + _workingDefinition.side1.sectorIds[si] = si + 1; + + for(int si = 0; si < 8; si++) + _workingDefinition.side2.sectorIds[si] = si + 1; + } + + break; + case FormatByte.k360: + case FormatByte.k360Alt: + case FormatByte.k360Alt2: + if(imagePlugin.Info.SectorSize == 512 && + imagePlugin.Info.Sectors == 720) + { + _cpmFound = true; + firstDirectorySector86 = 36; + + _dpb = new DiscParameterBlock + { + al0 = 0x80, + al1 = 0, + blm = 0x0F, + bsh = 4, + cks = 0x10, + drm = 0x3F, + dsm = 0, // Unknown. Needed? + exm = 1, + off = 4, + phm = 3, + psh = 2, + spt = 9 * 4 + }; + + _workingDefinition = new CpmDefinition + { + al0 = _dpb.al0, + al1 = _dpb.al1, + bitrate = "LOW", + blm = _dpb.blm, + bsh = _dpb.bsh, + bytesPerSector = 512, + cylinders = 40, + drm = _dpb.drm, + dsm = _dpb.dsm, + encoding = "MFM", + evenOdd = false, + exm = _dpb.exm, + label = null, + comment = "CP/M-86 floppy identifier", + ofs = _dpb.off, + sectorsPerTrack = 9, + side1 = new Side + { + sideId = 0, + sectorIds = new int[9] + }, + order = "SIDES", + side2 = new Side + { + sideId = 1, + sectorIds = new int[9] + }, + skew = 0, + sofs = 0 + }; + + for(int si = 0; si < 9; si++) + _workingDefinition.side1.sectorIds[si] = si + 1; + + for(int si = 0; si < 9; si++) + _workingDefinition.side2.sectorIds[si] = si + 1; + } + + break; + case FormatByte.k720: + case FormatByte.k720Alt: + if(imagePlugin.Info.SectorSize == 512 && + imagePlugin.Info.Sectors == 1440) + { + _cpmFound = true; + firstDirectorySector86 = 36; + + _dpb = new DiscParameterBlock + { + al0 = 0xF0, + al1 = 0, + blm = 0x0F, + bsh = 4, + cks = 0x40, + drm = 0xFF, + dsm = 0x15E, + exm = 0, + off = 4, + phm = 3, + psh = 2, + spt = 9 * 4 + }; + + _workingDefinition = new CpmDefinition + { + al0 = _dpb.al0, + al1 = _dpb.al1, + bitrate = "LOW", + blm = _dpb.blm, + bsh = _dpb.bsh, + bytesPerSector = 512, + cylinders = 80, + drm = _dpb.drm, + dsm = _dpb.dsm, + encoding = "MFM", + evenOdd = false, + exm = _dpb.exm, + label = null, + comment = "CP/M-86 floppy identifier", + ofs = _dpb.off, + sectorsPerTrack = 9, + side1 = new Side + { + sideId = 0, + sectorIds = new int[9] + }, + order = "SIDES", + side2 = new Side + { + sideId = 1, + sectorIds = new int[9] + }, + skew = 0, + sofs = 0 + }; + + for(int si = 0; si < 9; si++) + _workingDefinition.side1.sectorIds[si] = si + 1; + + for(int si = 0; si < 9; si++) + _workingDefinition.side2.sectorIds[si] = si + 1; + } + + break; + case FormatByte.f720: + if(imagePlugin.Info.SectorSize == 512 && + imagePlugin.Info.Sectors == 1440) + { + _cpmFound = true; + firstDirectorySector86 = 18; + + _dpb = new DiscParameterBlock + { + al0 = 0xF0, + al1 = 0, + blm = 0x0F, + bsh = 4, + cks = 0x40, + drm = 0xFF, + dsm = 0x162, + exm = 0, + off = 2, + phm = 3, + psh = 2, + spt = 9 * 4 + }; + + _workingDefinition = new CpmDefinition + { + al0 = _dpb.al0, + al1 = _dpb.al1, + bitrate = "LOW", + blm = _dpb.blm, + bsh = _dpb.bsh, + bytesPerSector = 512, + cylinders = 80, + drm = _dpb.drm, + dsm = _dpb.dsm, + encoding = "MFM", + evenOdd = false, + exm = _dpb.exm, + label = null, + comment = "CP/M-86 floppy identifier", + ofs = _dpb.off, + sectorsPerTrack = 9, + side1 = new Side + { + sideId = 0, + sectorIds = new int[9] + }, + order = "CYLINDERS", + side2 = new Side + { + sideId = 1, + sectorIds = new int[9] + }, + skew = 0, + sofs = 0 + }; + + for(int si = 0; si < 9; si++) + _workingDefinition.side1.sectorIds[si] = si + 1; + + for(int si = 0; si < 9; si++) + _workingDefinition.side2.sectorIds[si] = si + 1; + } + + break; + case FormatByte.f1200: + if(imagePlugin.Info.SectorSize == 512 && + imagePlugin.Info.Sectors == 2400) + { + _cpmFound = true; + firstDirectorySector86 = 30; + + _dpb = new DiscParameterBlock + { + al0 = 0xC0, + al1 = 0, + blm = 0x1F, + bsh = 5, + cks = 0x40, + drm = 0xFF, + dsm = 0x127, + exm = 1, + off = 2, + phm = 3, + psh = 2, + spt = 15 * 4 + }; + + _workingDefinition = new CpmDefinition + { + al0 = _dpb.al0, + al1 = _dpb.al1, + bitrate = "HIGH", + blm = _dpb.blm, + bsh = _dpb.bsh, + bytesPerSector = 512, + cylinders = 80, + drm = _dpb.drm, + dsm = _dpb.dsm, + encoding = "MFM", + evenOdd = false, + exm = _dpb.exm, + label = null, + comment = "CP/M-86 floppy identifier", + ofs = _dpb.off, + sectorsPerTrack = 15, + side1 = new Side + { + sideId = 0, + sectorIds = new int[15] + }, + order = "CYLINDERS", + side2 = new Side + { + sideId = 1, + sectorIds = new int[15] + }, + skew = 0, + sofs = 0 + }; + + for(int si = 0; si < 15; si++) + _workingDefinition.side1.sectorIds[si] = si + 1; + + for(int si = 0; si < 15; si++) + _workingDefinition.side2.sectorIds[si] = si + 1; + } + + break; + case FormatByte.f1440: + if(imagePlugin.Info.SectorSize == 512 && + imagePlugin.Info.Sectors == 2880) + { + _cpmFound = true; + firstDirectorySector86 = 36; + + _dpb = new DiscParameterBlock + { + al0 = 0xC0, + al1 = 0, + blm = 0x1F, + bsh = 5, + cks = 0x40, + drm = 0xFF, + dsm = 0x162, + exm = 1, + off = 2, + phm = 3, + psh = 2, + spt = 18 * 4 + }; + + _workingDefinition = new CpmDefinition + { + al0 = _dpb.al0, + al1 = _dpb.al1, + bitrate = "LOW", + blm = _dpb.blm, + bsh = _dpb.bsh, + bytesPerSector = 512, + cylinders = 80, + drm = _dpb.drm, + dsm = _dpb.dsm, + encoding = "MFM", + evenOdd = false, + exm = _dpb.exm, + label = null, + comment = "CP/M-86 floppy identifier", + ofs = _dpb.off, + sectorsPerTrack = 18, + side1 = new Side + { + sideId = 0, + sectorIds = new int[18] + }, + order = "CYLINDERS", + side2 = new Side + { + sideId = 1, + sectorIds = new int[18] + }, + skew = 0, + sofs = 0 + }; + + for(int si = 0; si < 18; si++) + _workingDefinition.side1.sectorIds[si] = si + 1; + + for(int si = 0; si < 18; si++) + _workingDefinition.side2.sectorIds[si] = si + 1; + } + + break; + } + + if(_cpmFound) + { + uint directoryLength = (uint)(((ulong)_dpb.drm + 1) * 32 / imagePlugin.Info.SectorSize); + + errno = imagePlugin.ReadSectors(firstDirectorySector86 + partition.Start, directoryLength, + out directory); + + AaruConsole.DebugWriteLine("CP/M Plugin", "Found CP/M-86 floppy identifier."); + } } } @@ -1003,10 +1022,13 @@ namespace Aaru.Filesystems for(int p = 0; p < dirLen; p++) { - byte[] dirSector = - imagePlugin.ReadSector((ulong)((int)offset + (int)partition.Start + - (p / _sectorMask.Length * _sectorMask.Length) + - _sectorMask[p % _sectorMask.Length])); + errno = + imagePlugin. + ReadSector((ulong)((int)offset + (int)partition.Start + (p / _sectorMask.Length * _sectorMask.Length) + _sectorMask[p % _sectorMask.Length]), + out byte[] dirSector); + + if(errno != ErrorNumber.NoError) + break; ms.Write(dirSector, 0, dirSector.Length); } diff --git a/Aaru.Filesystems/CPM/Super.cs b/Aaru.Filesystems/CPM/Super.cs index 836b781a0..846b65987 100644 --- a/Aaru.Filesystems/CPM/Super.cs +++ b/Aaru.Filesystems/CPM/Super.cs @@ -149,10 +149,13 @@ namespace Aaru.Filesystems for(int p = 0; p <= (int)(partition.End - partition.Start); p++) { - byte[] readSector = - _device.ReadSector((ulong)((int)partition.Start + - (p / _sectorMask.Length * _sectorMask.Length) + - _sectorMask[p % _sectorMask.Length])); + ErrorNumber errno = + _device. + ReadSector((ulong)((int)partition.Start + (p / _sectorMask.Length * _sectorMask.Length) + _sectorMask[p % _sectorMask.Length]), + out byte[] readSector); + + if(errno != ErrorNumber.NoError) + return errno; if(_workingDefinition.complement) for(int b = 0; b < readSector.Length; b++) diff --git a/Aaru.Filesystems/Cram.cs b/Aaru.Filesystems/Cram.cs index 77f984f89..8d69cdd4e 100644 --- a/Aaru.Filesystems/Cram.cs +++ b/Aaru.Filesystems/Cram.cs @@ -35,6 +35,7 @@ using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; using System.Text; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Aaru.Helpers; using Schemas; @@ -60,7 +61,7 @@ namespace Aaru.Filesystems /// public string Name => "Cram filesystem"; /// - public Guid Id => new Guid("F8F6E46F-7A2A-48E3-9C0A-46AF4DC29E09"); + public Guid Id => new("F8F6E46F-7A2A-48E3-9C0A-46AF4DC29E09"); /// public string Author => "Natalia Portillo"; @@ -70,7 +71,10 @@ namespace Aaru.Filesystems if(partition.Start >= partition.End) return false; - byte[] sector = imagePlugin.ReadSector(partition.Start); + ErrorNumber errno = imagePlugin.ReadSector(partition.Start, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return false; uint magic = BitConverter.ToUInt32(sector, 0x00); @@ -81,9 +85,14 @@ namespace Aaru.Filesystems public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information, Encoding encoding) { - Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15"); - byte[] sector = imagePlugin.ReadSector(partition.Start); - uint magic = BitConverter.ToUInt32(sector, 0x00); + Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15"); + information = ""; + ErrorNumber errno = imagePlugin.ReadSector(partition.Start, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return; + + uint magic = BitConverter.ToUInt32(sector, 0x00); var crSb = new SuperBlock(); bool littleEndian = true; diff --git a/Aaru.Filesystems/ECMA67.cs b/Aaru.Filesystems/ECMA67.cs index 88cc2c8e9..2aed4ff2f 100644 --- a/Aaru.Filesystems/ECMA67.cs +++ b/Aaru.Filesystems/ECMA67.cs @@ -35,6 +35,7 @@ using System.Linq; using System.Runtime.InteropServices; using System.Text; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Schemas; using Marshal = Aaru.Helpers.Marshal; @@ -55,7 +56,7 @@ namespace Aaru.Filesystems /// public string Name => "ECMA-67"; /// - public Guid Id => new Guid("62A2D44A-CBC1-4377-B4B6-28C5C92034A1"); + public Guid Id => new("62A2D44A-CBC1-4377-B4B6-28C5C92034A1"); /// public FileSystemType XmlFsType { get; private set; } /// @@ -70,7 +71,10 @@ namespace Aaru.Filesystems if(partition.End < 8) return false; - byte[] sector = imagePlugin.ReadSector(6); + ErrorNumber errno = imagePlugin.ReadSector(6, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return false; if(sector.Length != 128) return false; @@ -84,8 +88,12 @@ namespace Aaru.Filesystems public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information, Encoding encoding) { - Encoding = encoding ?? Encoding.GetEncoding("iso-8859-1"); - byte[] sector = imagePlugin.ReadSector(6); + Encoding = encoding ?? Encoding.GetEncoding("iso-8859-1"); + information = ""; + ErrorNumber errno = imagePlugin.ReadSector(6, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return; var sbInformation = new StringBuilder(); diff --git a/Aaru.Filesystems/EFS.cs b/Aaru.Filesystems/EFS.cs index 181659147..15fcac3f5 100644 --- a/Aaru.Filesystems/EFS.cs +++ b/Aaru.Filesystems/EFS.cs @@ -76,7 +76,8 @@ namespace Aaru.Filesystems if((Marshal.SizeOf() + 0x200) % imagePlugin.Info.SectorSize != 0) sbSize++; - byte[] sector = imagePlugin.ReadSectors(partition.Start, sbSize); + var errno = imagePlugin.ReadSectors(partition.Start, sbSize, out byte[] sector); + if(errno != ErrorNumber.NoError) return false; if(sector.Length < Marshal.SizeOf()) return false; @@ -101,7 +102,8 @@ namespace Aaru.Filesystems if(Marshal.SizeOf() % imagePlugin.Info.SectorSize != 0) sbSize++; - byte[] sector = imagePlugin.ReadSectors(partition.Start + 1, sbSize); + var errno = imagePlugin.ReadSectors(partition.Start + 1, sbSize, out byte[] sector); + if(errno != ErrorNumber.NoError) return false; if(sector.Length < Marshal.SizeOf()) return false; @@ -139,7 +141,8 @@ namespace Aaru.Filesystems if((Marshal.SizeOf() + 0x400) % imagePlugin.Info.SectorSize != 0) sbSize++; - byte[] sector = imagePlugin.ReadSectors(partition.Start, sbSize); + var errno = imagePlugin.ReadSectors(partition.Start, sbSize, out byte[] sector); + if(errno != ErrorNumber.NoError) return; if(sector.Length < Marshal.SizeOf()) return; @@ -160,7 +163,8 @@ namespace Aaru.Filesystems if(Marshal.SizeOf() % imagePlugin.Info.SectorSize != 0) sbSize++; - byte[] sector = imagePlugin.ReadSectors(partition.Start + 1, sbSize); + var errno = imagePlugin.ReadSectors(partition.Start + 1, sbSize, out byte[] sector); + if(errno != ErrorNumber.NoError) return; if(sector.Length < Marshal.SizeOf()) return; diff --git a/Aaru.Filesystems/F2FS.cs b/Aaru.Filesystems/F2FS.cs index a0639d5bd..2d076bb65 100644 --- a/Aaru.Filesystems/F2FS.cs +++ b/Aaru.Filesystems/F2FS.cs @@ -35,6 +35,7 @@ using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; using System.Text; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Aaru.Helpers; using Schemas; @@ -63,7 +64,7 @@ namespace Aaru.Filesystems /// public string Name => "F2FS Plugin"; /// - public Guid Id => new Guid("82B0920F-5F0D-4063-9F57-ADE0AE02ECE5"); + public Guid Id => new("82B0920F-5F0D-4063-9F57-ADE0AE02ECE5"); /// public string Author => "Natalia Portillo"; @@ -87,7 +88,10 @@ namespace Aaru.Filesystems if(partition.Start + sbAddr + sbSize >= partition.End) return false; - byte[] sector = imagePlugin.ReadSectors(partition.Start + sbAddr, sbSize); + ErrorNumber errno = imagePlugin.ReadSectors(partition.Start + sbAddr, sbSize, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return false; if(sector.Length < Marshal.SizeOf()) return false; @@ -118,7 +122,10 @@ namespace Aaru.Filesystems if(Marshal.SizeOf() % imagePlugin.Info.SectorSize != 0) sbSize++; - byte[] sector = imagePlugin.ReadSectors(partition.Start + sbAddr, sbSize); + ErrorNumber errno = imagePlugin.ReadSectors(partition.Start + sbAddr, sbSize, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return; if(sector.Length < Marshal.SizeOf()) return; diff --git a/Aaru.Filesystems/FAT/BPB.cs b/Aaru.Filesystems/FAT/BPB.cs index 91e9ab343..15c5f5597 100644 --- a/Aaru.Filesystems/FAT/BPB.cs +++ b/Aaru.Filesystems/FAT/BPB.cs @@ -32,7 +32,6 @@ using System; using System.IO; -using System.Linq; using System.Text; using Aaru.CommonTypes; using Aaru.CommonTypes.Enums; @@ -53,6 +52,7 @@ namespace Aaru.Filesystems minBootNearJump = 0; andosOemCorrect = false; bootable = false; + ErrorNumber errno; humanBpb = Marshal.ByteArrayToStructureBigEndian(bpbSector); atariBpb = Marshal.ByteArrayToStructureLittleEndian(bpbSector); @@ -381,20 +381,23 @@ namespace Aaru.Filesystems byte z80Di = bpbSector[0]; // First FAT1 sector resides at LBA 0x14 - byte[] fat1Sector0 = imagePlugin.ReadSector(0x14); + imagePlugin.ReadSector(0x14, out byte[] fat1Sector0); // First FAT2 sector resides at LBA 0x1A - byte[] fat2Sector0 = imagePlugin.ReadSector(0x1A); - bool equalFatIds = fat1Sector0[0] == fat2Sector0[0] && fat1Sector0[1] == fat2Sector0[1]; + imagePlugin.ReadSector(0x1A, out byte[] fat2Sector0); + bool equalFatIds = fat1Sector0[0] == fat2Sector0[0] && fat1Sector0[1] == fat2Sector0[1]; // Volume is software interleaved 2:1 var rootMs = new MemoryStream(); - foreach(byte[] tmp in from ulong rootSector in new[] + foreach(ulong rootSector in new[] { 0x17, 0x19, 0x1B, 0x1D, 0x1E, 0x20 - } select imagePlugin.ReadSector(rootSector)) + }) + { + imagePlugin.ReadSector(rootSector, out byte[] tmp); rootMs.Write(tmp, 0, tmp.Length); + } byte[] rootDir = rootMs.ToArray(); bool validRootDir = true; @@ -455,7 +458,7 @@ namespace Aaru.Filesystems !useApricotBpb && !useDecRainbowBpb) { - byte[] fatSector = imagePlugin.ReadSector(1 + partition.Start); + imagePlugin.ReadSector(1 + partition.Start, out byte[] fatSector); switch(fatSector[0]) { @@ -812,9 +815,9 @@ namespace Aaru.Filesystems if(apricotBpb.bootLocation > 0 && apricotBpb.bootLocation + apricotBpb.bootSize < imagePlugin.Info.Sectors) - fakeBpb.boot_code = imagePlugin.ReadSectors(apricotBpb.bootLocation, + imagePlugin.ReadSectors(apricotBpb.bootLocation, (uint)(apricotBpb.sectorSize * apricotBpb.bootSize) / - imagePlugin.Info.SectorSize); + imagePlugin.Info.SectorSize, out fakeBpb.boot_code); return BpbKind.Apricot; } diff --git a/Aaru.Filesystems/FAT/Dir.cs b/Aaru.Filesystems/FAT/Dir.cs index f7d30423d..e1f5e64d0 100644 --- a/Aaru.Filesystems/FAT/Dir.cs +++ b/Aaru.Filesystems/FAT/Dir.cs @@ -61,6 +61,7 @@ namespace Aaru.Filesystems public ErrorNumber ReadDir(string path, out List contents) { contents = null; + ErrorNumber errno = ErrorNumber.NoError; if(!_mounted) return ErrorNumber.AccessDenied; @@ -138,8 +139,11 @@ namespace Aaru.Filesystems for(int i = 0; i < clusters.Length; i++) { - byte[] buffer = _image.ReadSectors(_firstClusterSector + (clusters[i] * _sectorsPerCluster), - _sectorsPerCluster); + errno = _image.ReadSectors(_firstClusterSector + (clusters[i] * _sectorsPerCluster), + _sectorsPerCluster, out byte[] buffer); + + if(errno != ErrorNumber.NoError) + return errno; Array.Copy(buffer, 0, directoryBuffer, i * _bytesPerCluster, _bytesPerCluster); } diff --git a/Aaru.Filesystems/FAT/File.cs b/Aaru.Filesystems/FAT/File.cs index 9866c58be..3340bb1c0 100644 --- a/Aaru.Filesystems/FAT/File.cs +++ b/Aaru.Filesystems/FAT/File.cs @@ -91,6 +91,8 @@ namespace Aaru.Filesystems /// public ErrorNumber Read(string path, long offset, long size, ref byte[] buf) { + ErrorNumber errno; + if(!_mounted) return ErrorNumber.AccessDenied; @@ -135,9 +137,11 @@ namespace Aaru.Filesystems if(i + firstCluster >= clusters.Length) return ErrorNumber.InvalidArgument; - byte[] buffer = - _image.ReadSectors(_firstClusterSector + (clusters[i + firstCluster] * _sectorsPerCluster), - _sectorsPerCluster); + errno = _image.ReadSectors(_firstClusterSector + (clusters[i + firstCluster] * _sectorsPerCluster), + _sectorsPerCluster, out byte[] buffer); + + if(errno != ErrorNumber.NoError) + return errno; ms.Write(buffer, 0, buffer.Length); } @@ -239,8 +243,11 @@ namespace Aaru.Filesystems int nextEntry = (int)(nextCluster % _fatEntriesPerSector); - ulong currentSector = nextSector; - byte[] fatData = _image.ReadSector(currentSector); + ulong currentSector = nextSector; + ErrorNumber errno = _image.ReadSector(currentSector, out byte[] fatData); + + if(errno != ErrorNumber.NoError) + return null; if(_fat32) while((nextCluster & FAT32_MASK) > 0 && @@ -250,7 +257,11 @@ namespace Aaru.Filesystems if(currentSector != nextSector) { - fatData = _image.ReadSector(nextSector); + errno = _image.ReadSector(nextSector, out fatData); + + if(errno != ErrorNumber.NoError) + return null; + currentSector = nextSector; } diff --git a/Aaru.Filesystems/FAT/Info.cs b/Aaru.Filesystems/FAT/Info.cs index 7c71ef3f5..1e8b4635e 100644 --- a/Aaru.Filesystems/FAT/Info.cs +++ b/Aaru.Filesystems/FAT/Info.cs @@ -77,8 +77,15 @@ namespace Aaru.Filesystems uint sectorsPerBpb = imagePlugin.Info.SectorSize < 512 ? 512 / imagePlugin.Info.SectorSize : 1; - byte[] bpbSector = imagePlugin.ReadSectors(0 + partition.Start, sectorsPerBpb); - byte[] fatSector = imagePlugin.ReadSector(sectorsPerBpb + partition.Start); + ErrorNumber errno = imagePlugin.ReadSectors(0 + partition.Start, sectorsPerBpb, out byte[] bpbSector); + + if(errno != ErrorNumber.NoError) + return false; + + errno = imagePlugin.ReadSector(sectorsPerBpb + partition.Start, out byte[] fatSector); + + if(errno != ErrorNumber.NoError) + return false; HumanParameterBlock humanBpb = Marshal.ByteArrayToStructureBigEndian(bpbSector); @@ -217,8 +224,11 @@ namespace Aaru.Filesystems // HPFS if(16 + partition.Start <= partition.End) { - byte[] hpfsSbSector = - imagePlugin.ReadSector(16 + partition.Start); // Seek to superblock, on logical sector 16 + errno = imagePlugin.ReadSector(16 + partition.Start, + out byte[] hpfsSbSector); // Seek to superblock, on logical sector 16 + + if(errno != ErrorNumber.NoError) + return false; uint hpfsMagic1 = BitConverter.ToUInt32(hpfsSbSector, 0x000); uint hpfsMagic2 = BitConverter.ToUInt32(hpfsSbSector, 0x004); @@ -282,20 +292,34 @@ namespace Aaru.Filesystems byte z80Di = bpbSector[0]; // First FAT1 sector resides at LBA 0x14 - byte[] fat1Sector0 = imagePlugin.ReadSector(0x14); + errno = imagePlugin.ReadSector(0x14, out byte[] fat1Sector0); + + if(errno != ErrorNumber.NoError) + return false; // First FAT2 sector resides at LBA 0x1A - byte[] fat2Sector0 = imagePlugin.ReadSector(0x1A); - bool equalFatIds = fat1Sector0[0] == fat2Sector0[0] && fat1Sector0[1] == fat2Sector0[1]; + errno = imagePlugin.ReadSector(0x1A, out byte[] fat2Sector0); + + if(errno != ErrorNumber.NoError) + return false; + + bool equalFatIds = fat1Sector0[0] == fat2Sector0[0] && fat1Sector0[1] == fat2Sector0[1]; // Volume is software interleaved 2:1 var rootMs = new MemoryStream(); - foreach(byte[] tmp in from ulong rootSector in new ulong[] + foreach(ulong rootSector in new ulong[] { 0x17, 0x19, 0x1B, 0x1D, 0x1E, 0x20 - } select imagePlugin.ReadSector(rootSector)) + }) + { + errno = imagePlugin.ReadSector(rootSector, out byte[] tmp); + + if(errno != ErrorNumber.NoError) + return false; + rootMs.Write(tmp, 0, tmp.Length); + } byte[] rootDir = rootMs.ToArray(); bool validRootDir = true; @@ -395,7 +419,10 @@ namespace Aaru.Filesystems AaruConsole.DebugWriteLine("FAT plugin", "2nd fat starts at = {0}", fat2SectorNo); - byte[] fat2Sector = imagePlugin.ReadSector(fat2SectorNo); + errno = imagePlugin.ReadSector(fat2SectorNo, out byte[] fat2Sector); + + if(errno != ErrorNumber.NoError) + return false; fat2 = fat2Sector[1]; fat3 = fat2Sector[2]; @@ -413,13 +440,17 @@ namespace Aaru.Filesystems { Encoding = encoding ?? Encoding.GetEncoding("IBM437"); information = ""; + ErrorNumber errno; var sb = new StringBuilder(); XmlFsType = new FileSystemType(); uint sectorsPerBpb = imagePlugin.Info.SectorSize < 512 ? 512 / imagePlugin.Info.SectorSize : 1; - byte[] bpbSector = imagePlugin.ReadSectors(0 + partition.Start, sectorsPerBpb); + errno = imagePlugin.ReadSectors(0 + partition.Start, sectorsPerBpb, out byte[] bpbSector); + + if(errno != ErrorNumber.NoError) + return; BpbKind bpbKind = DetectBpbKind(bpbSector, imagePlugin, partition, out BiosParameterBlockEbpb fakeBpb, out HumanParameterBlock humanBpb, out AtariParameterBlock atariBpb, @@ -587,7 +618,11 @@ namespace Aaru.Filesystems if(fat32Bpb.fsinfo_sector + partition.Start <= partition.End) { - byte[] fsinfoSector = imagePlugin.ReadSector(fat32Bpb.fsinfo_sector + partition.Start); + errno = imagePlugin.ReadSector(fat32Bpb.fsinfo_sector + partition.Start, + out byte[] fsinfoSector); + + if(errno != ErrorNumber.NoError) + return; FsInfoSector fsInfo = Marshal.ByteArrayToStructureLittleEndian(fsinfoSector); @@ -716,7 +751,10 @@ namespace Aaru.Filesystems sectorsPerRealSector = fakeBpb.bps / imagePlugin.Info.SectorSize; _fatFirstSector = partition.Start + (_reservedSectors * sectorsPerRealSector); - byte[] fatBytes = imagePlugin.ReadSectors(_fatFirstSector, fakeBpb.spfat); + errno = imagePlugin.ReadSectors(_fatFirstSector, fakeBpb.spfat, out byte[] fatBytes); + + if(errno != ErrorNumber.NoError) + return; int pos = 0; @@ -984,18 +1022,28 @@ namespace Aaru.Filesystems if(rootDirectorySector + partition.Start < partition.End && imagePlugin.Info.XmlMediaType != XmlMediaType.OpticalDisc) { - byte[] rootDirectory = - imagePlugin.ReadSectors(rootDirectorySector + partition.Start, sectorsForRootDirectory); + errno = imagePlugin.ReadSectors(rootDirectorySector + partition.Start, sectorsForRootDirectory, + out byte[] rootDirectory); + + if(errno != ErrorNumber.NoError) + return; if(bpbKind == BpbKind.DecRainbow) { var rootMs = new MemoryStream(); - foreach(byte[] tmp in from ulong rootSector in new[] + foreach(ulong rootSector in new[] { 0x17, 0x19, 0x1B, 0x1D, 0x1E, 0x20 - } select imagePlugin.ReadSector(rootSector)) + }) + { + errno = imagePlugin.ReadSector(rootSector, out byte[] tmp); + + if(errno != ErrorNumber.NoError) + return; + rootMs.Write(tmp, 0, tmp.Length); + } rootDirectory = rootMs.ToArray(); } diff --git a/Aaru.Filesystems/FAT/Super.cs b/Aaru.Filesystems/FAT/Super.cs index 9b46053f9..c966cd2ad 100644 --- a/Aaru.Filesystems/FAT/Super.cs +++ b/Aaru.Filesystems/FAT/Super.cs @@ -59,6 +59,7 @@ namespace Aaru.Filesystems Dictionary options, string @namespace) { XmlFsType = new FileSystemType(); + ErrorNumber errno; options ??= GetDefaultOptions(); @@ -101,7 +102,10 @@ namespace Aaru.Filesystems uint sectorsPerBpb = imagePlugin.Info.SectorSize < 512 ? 512 / imagePlugin.Info.SectorSize : 1; - byte[] bpbSector = imagePlugin.ReadSectors(0 + partition.Start, sectorsPerBpb); + errno = imagePlugin.ReadSectors(0 + partition.Start, sectorsPerBpb, out byte[] bpbSector); + + if(errno != ErrorNumber.NoError) + return errno; BpbKind bpbKind = DetectBpbKind(bpbSector, imagePlugin, partition, out BiosParameterBlockEbpb fakeBpb, out HumanParameterBlock humanBpb, out AtariParameterBlock atariBpb, @@ -222,7 +226,11 @@ namespace Aaru.Filesystems if(fat32Bpb.fsinfo_sector + partition.Start <= partition.End) { - byte[] fsinfoSector = imagePlugin.ReadSector(fat32Bpb.fsinfo_sector + partition.Start); + errno = imagePlugin.ReadSector(fat32Bpb.fsinfo_sector + partition.Start, + out byte[] fsinfoSector); + + if(errno != ErrorNumber.NoError) + return errno; FsInfoSector fsInfo = Marshal.ByteArrayToStructureLittleEndian(fsinfoSector); @@ -323,7 +331,10 @@ namespace Aaru.Filesystems sectorsPerRealSector = fakeBpb.bps / imagePlugin.Info.SectorSize; _fatFirstSector = partition.Start + (_reservedSectors * sectorsPerRealSector); - byte[] fatBytes = imagePlugin.ReadSectors(_fatFirstSector, fakeBpb.spfat); + errno = imagePlugin.ReadSectors(_fatFirstSector, fakeBpb.spfat, out byte[] fatBytes); + + if(errno != ErrorNumber.NoError) + return errno; int pos = 0; @@ -535,17 +546,27 @@ namespace Aaru.Filesystems if(!_fat32) { _firstClusterSector = firstRootSector + sectorsForRootDirectory - (_sectorsPerCluster * 2); - rootDirectory = imagePlugin.ReadSectors(firstRootSector, sectorsForRootDirectory); + errno = imagePlugin.ReadSectors(firstRootSector, sectorsForRootDirectory, out rootDirectory); + + if(errno != ErrorNumber.NoError) + return errno; if(bpbKind == BpbKind.DecRainbow) { var rootMs = new MemoryStream(); - foreach(byte[] tmp in from ulong rootSector in new[] + foreach(ulong rootSector in new[] { 0x17, 0x19, 0x1B, 0x1D, 0x1E, 0x20 - } select imagePlugin.ReadSector(rootSector)) + }) + { + errno = imagePlugin.ReadSector(rootSector, out byte[] tmp); + + if(errno != ErrorNumber.NoError) + return errno; + rootMs.Write(tmp, 0, tmp.Length); + } rootDirectory = rootMs.ToArray(); } @@ -558,11 +579,14 @@ namespace Aaru.Filesystems var rootMs = new MemoryStream(); uint[] rootDirectoryClusters = GetClusters(rootDirectoryCluster); - foreach(byte[] buffer in rootDirectoryClusters.Select(cluster => - imagePlugin. - ReadSectors(_firstClusterSector + (cluster * _sectorsPerCluster), - _sectorsPerCluster))) + foreach(uint cluster in rootDirectoryClusters) { + errno = imagePlugin.ReadSectors(_firstClusterSector + (cluster * _sectorsPerCluster), + _sectorsPerCluster, out byte[] buffer); + + if(errno != ErrorNumber.NoError) + return errno; + rootMs.Write(buffer, 0, buffer.Length); } @@ -848,7 +872,10 @@ namespace Aaru.Filesystems { AaruConsole.DebugWriteLine("FAT plugin", "Reading FAT12"); - byte[] fatBytes = imagePlugin.ReadSectors(_fatFirstSector, _sectorsPerFat); + errno = imagePlugin.ReadSectors(_fatFirstSector, _sectorsPerFat, out byte[] fatBytes); + + if(errno != ErrorNumber.NoError) + return errno; int pos = 0; @@ -862,7 +889,10 @@ namespace Aaru.Filesystems firstFatEntries[pos++] = (ushort)(((fatBytes[i + 1] & 0xF0) >> 4) + (fatBytes[i + 2] << 4)); } - fatBytes = imagePlugin.ReadSectors(_fatFirstSector + _sectorsPerFat, _sectorsPerFat); + errno = imagePlugin.ReadSectors(_fatFirstSector + _sectorsPerFat, _sectorsPerFat, out fatBytes); + + if(errno != ErrorNumber.NoError) + return errno; _fatEntries = new ushort[_statfs.Blocks]; @@ -911,12 +941,18 @@ namespace Aaru.Filesystems { AaruConsole.DebugWriteLine("FAT plugin", "Reading FAT16"); - byte[] fatBytes = imagePlugin.ReadSectors(_fatFirstSector, _sectorsPerFat); + errno = imagePlugin.ReadSectors(_fatFirstSector, _sectorsPerFat, out byte[] fatBytes); + + if(errno != ErrorNumber.NoError) + return errno; AaruConsole.DebugWriteLine("FAT plugin", "Casting FAT"); firstFatEntries = MemoryMarshal.Cast(fatBytes).ToArray(); - fatBytes = imagePlugin.ReadSectors(_fatFirstSector + _sectorsPerFat, _sectorsPerFat); + errno = imagePlugin.ReadSectors(_fatFirstSector + _sectorsPerFat, _sectorsPerFat, out fatBytes); + + if(errno != ErrorNumber.NoError) + return errno; AaruConsole.DebugWriteLine("FAT plugin", "Casting FAT"); secondFatEntries = MemoryMarshal.Cast(fatBytes).ToArray(); diff --git a/Aaru.Filesystems/FAT/Xattr.cs b/Aaru.Filesystems/FAT/Xattr.cs index 769b8d8d7..0e7fa3211 100644 --- a/Aaru.Filesystems/FAT/Xattr.cs +++ b/Aaru.Filesystems/FAT/Xattr.cs @@ -133,11 +133,14 @@ namespace Aaru.Filesystems var eaMs = new MemoryStream(); uint[] rootDirectoryClusters = GetClusters(entryFat32Ea.start_cluster); - foreach(byte[] buffer in rootDirectoryClusters.Select(cluster => - _image. - ReadSectors(_firstClusterSector + (cluster * _sectorsPerCluster), - _sectorsPerCluster))) + foreach(uint cluster in rootDirectoryClusters) { + ErrorNumber errno = _image.ReadSectors(_firstClusterSector + (cluster * _sectorsPerCluster), + _sectorsPerCluster, out byte[] buffer); + + if(errno != ErrorNumber.NoError) + return null; + eaMs.Write(buffer, 0, buffer.Length); } @@ -234,10 +237,16 @@ namespace Aaru.Filesystems var eaDataMs = new MemoryStream(); - foreach(byte[] buffer in GetClusters(_eaDirEntry.start_cluster). - Select(cluster => _image.ReadSectors(_firstClusterSector + (cluster * _sectorsPerCluster), - _sectorsPerCluster))) + foreach(uint cluster in GetClusters(_eaDirEntry.start_cluster)) + { + ErrorNumber errno = _image.ReadSectors(_firstClusterSector + (cluster * _sectorsPerCluster), + _sectorsPerCluster, out byte[] buffer); + + if(errno != ErrorNumber.NoError) + break; + eaDataMs.Write(buffer, 0, buffer.Length); + } _cachedEaData = eaDataMs.ToArray(); } diff --git a/Aaru.Filesystems/FATX/Dir.cs b/Aaru.Filesystems/FATX/Dir.cs index 74f6560b6..5ff3160f1 100644 --- a/Aaru.Filesystems/FATX/Dir.cs +++ b/Aaru.Filesystems/FATX/Dir.cs @@ -109,9 +109,12 @@ namespace Aaru.Filesystems for(int i = 0; i < clusters.Length; i++) { - byte[] buffer = + ErrorNumber errno = _imagePlugin.ReadSectors(_firstClusterSector + ((clusters[i] - 1) * _sectorsPerCluster), - _sectorsPerCluster); + _sectorsPerCluster, out byte[] buffer); + + if(errno != ErrorNumber.NoError) + return errno; Array.Copy(buffer, 0, directoryBuffer, i * _bytesPerCluster, _bytesPerCluster); } diff --git a/Aaru.Filesystems/FATX/File.cs b/Aaru.Filesystems/FATX/File.cs index 945b14434..c0c225e10 100644 --- a/Aaru.Filesystems/FATX/File.cs +++ b/Aaru.Filesystems/FATX/File.cs @@ -125,10 +125,13 @@ namespace Aaru.Filesystems if(i + firstCluster >= clusters.Length) return ErrorNumber.InvalidArgument; - byte[] buffer = + ErrorNumber errno = _imagePlugin. ReadSectors(_firstClusterSector + ((clusters[i + firstCluster] - 1) * _sectorsPerCluster), - _sectorsPerCluster); + _sectorsPerCluster, out byte[] buffer); + + if(errno != ErrorNumber.NoError) + return errno; ms.Write(buffer, 0, buffer.Length); } diff --git a/Aaru.Filesystems/FATX/Info.cs b/Aaru.Filesystems/FATX/Info.cs index e976086a8..d06839565 100644 --- a/Aaru.Filesystems/FATX/Info.cs +++ b/Aaru.Filesystems/FATX/Info.cs @@ -32,6 +32,7 @@ using System.Text; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Aaru.Helpers; using Schemas; @@ -46,7 +47,10 @@ namespace Aaru.Filesystems if(imagePlugin.Info.SectorSize < 512) return false; - byte[] sector = imagePlugin.ReadSector(partition.Start); + ErrorNumber errno = imagePlugin.ReadSector(partition.Start, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return false; Superblock sb = Marshal.ByteArrayToStructureBigEndian(sector); @@ -65,7 +69,10 @@ namespace Aaru.Filesystems bool bigEndian = true; - byte[] sector = imagePlugin.ReadSector(partition.Start); + ErrorNumber errno = imagePlugin.ReadSector(partition.Start, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return; Superblock fatxSb = Marshal.ByteArrayToStructureBigEndian(sector); diff --git a/Aaru.Filesystems/FATX/Super.cs b/Aaru.Filesystems/FATX/Super.cs index 7e8082669..5a14be6ac 100644 --- a/Aaru.Filesystems/FATX/Super.cs +++ b/Aaru.Filesystems/FATX/Super.cs @@ -65,7 +65,10 @@ namespace Aaru.Filesystems AaruConsole.DebugWriteLine("Xbox FAT plugin", "Reading superblock"); - byte[] sector = imagePlugin.ReadSector(partition.Start); + ErrorNumber errno = imagePlugin.ReadSector(partition.Start, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return errno; _superblock = Marshal.ByteArrayToStructureLittleEndian(sector); @@ -150,7 +153,10 @@ namespace Aaru.Filesystems AaruConsole.DebugWriteLine("Xbox FAT plugin", "FAT is {0} sectors", fatSize); - buffer = imagePlugin.ReadSectors(_fatStartSector, fatSize); + errno = imagePlugin.ReadSectors(_fatStartSector, fatSize, out buffer); + + if(errno != ErrorNumber.NoError) + return errno; AaruConsole.DebugWriteLine("Xbox FAT plugin", "Casting FAT"); _fat32 = MemoryMarshal.Cast(buffer).ToArray(); @@ -182,7 +188,10 @@ namespace Aaru.Filesystems AaruConsole.DebugWriteLine("Xbox FAT plugin", "FAT is {0} sectors", fatSize); - buffer = imagePlugin.ReadSectors(_fatStartSector, fatSize); + errno = imagePlugin.ReadSectors(_fatStartSector, fatSize, out buffer); + + if(errno != ErrorNumber.NoError) + return errno; AaruConsole.DebugWriteLine("Xbox FAT plugin", "Casting FAT"); _fat16 = MemoryMarshal.Cast(buffer).ToArray(); @@ -217,9 +226,12 @@ namespace Aaru.Filesystems for(int i = 0; i < rootDirectoryClusters.Length; i++) { - buffer = + errno = imagePlugin.ReadSectors(_firstClusterSector + ((rootDirectoryClusters[i] - 1) * _sectorsPerCluster), - _sectorsPerCluster); + _sectorsPerCluster, out buffer); + + if(errno != ErrorNumber.NoError) + return errno; Array.Copy(buffer, 0, rootDirectoryBuffer, i * _bytesPerCluster, _bytesPerCluster); } diff --git a/Aaru.Filesystems/FFS.cs b/Aaru.Filesystems/FFS.cs index 843b85b26..329264da4 100644 --- a/Aaru.Filesystems/FFS.cs +++ b/Aaru.Filesystems/FFS.cs @@ -36,6 +36,7 @@ using System.Linq; using System.Runtime.InteropServices; using System.Text; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Aaru.Console; using Aaru.Helpers; @@ -102,7 +103,7 @@ namespace Aaru.Filesystems /// public string Name => "BSD Fast File System (aka UNIX File System, UFS)"; /// - public Guid Id => new Guid("CC90D342-05DB-48A8-988C-C1FE000034A3"); + public Guid Id => new("CC90D342-05DB-48A8-988C-C1FE000034A3"); /// public string Author => "Natalia Portillo"; @@ -130,12 +131,31 @@ namespace Aaru.Filesystems try { - return locations.Where(loc => partition.End > partition.Start + loc + sbSizeInSectors). - Select(loc => imagePlugin.ReadSectors(partition.Start + loc, sbSizeInSectors)). - Select(ufsSbSectors => BitConverter.ToUInt32(ufsSbSectors, 0x055C)). - Any(magic => magic == UFS_MAGIC || magic == UFS_CIGAM || magic == UFS_MAGIC_BW || - magic == UFS_CIGAM_BW || magic == UFS2_MAGIC || magic == UFS2_CIGAM || - magic == UFS_BAD_MAGIC || magic == UFS_BAD_CIGAM); + foreach(ulong loc in locations) + { + if(partition.End > partition.Start + loc + sbSizeInSectors) + { + ErrorNumber errno = + imagePlugin.ReadSectors(partition.Start + loc, sbSizeInSectors, out byte[] ufsSbSectors); + + if(errno != ErrorNumber.NoError) + continue; + + uint magic = BitConverter.ToUInt32(ufsSbSectors, 0x055C); + + if(magic == UFS_MAGIC || + magic == UFS_CIGAM || + magic == UFS_MAGIC_BW || + magic == UFS_CIGAM_BW || + magic == UFS2_MAGIC || + magic == UFS2_CIGAM || + magic == UFS_BAD_MAGIC || + magic == UFS_BAD_CIGAM) + return true; + } + } + + return false; } catch(Exception) { @@ -177,10 +197,16 @@ namespace Aaru.Filesystems 262144 / imagePlugin.Info.SectorSize }; + ErrorNumber errno; + foreach(ulong loc in locations.Where(loc => partition.End > partition.Start + loc + sb_size_in_sectors)) { - ufs_sb_sectors = imagePlugin.ReadSectors(partition.Start + loc, sb_size_in_sectors); - magic = BitConverter.ToUInt32(ufs_sb_sectors, 0x055C); + errno = imagePlugin.ReadSectors(partition.Start + loc, sb_size_in_sectors, out ufs_sb_sectors); + + if(errno != ErrorNumber.NoError) + continue; + + magic = BitConverter.ToUInt32(ufs_sb_sectors, 0x055C); if(magic == UFS_MAGIC || magic == UFS_CIGAM || @@ -255,7 +281,10 @@ namespace Aaru.Filesystems } // Fun with seeking follows on superblock reading! - ufs_sb_sectors = imagePlugin.ReadSectors(sb_offset, sb_size_in_sectors); + errno = imagePlugin.ReadSectors(sb_offset, sb_size_in_sectors, out ufs_sb_sectors); + + if(errno != ErrorNumber.NoError) + return; SuperBlock sb = Marshal.ByteArrayToStructureLittleEndian(ufs_sb_sectors); diff --git a/Aaru.Filesystems/Fossil.cs b/Aaru.Filesystems/Fossil.cs index 037ea69a8..c46245220 100644 --- a/Aaru.Filesystems/Fossil.cs +++ b/Aaru.Filesystems/Fossil.cs @@ -34,6 +34,7 @@ using System; using System.Runtime.InteropServices; using System.Text; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Aaru.Console; using Aaru.Helpers; @@ -59,7 +60,7 @@ namespace Aaru.Filesystems /// public string Name => "Fossil Filesystem Plugin"; /// - public Guid Id => new Guid("932BF104-43F6-494F-973C-45EF58A51DA9"); + public Guid Id => new("932BF104-43F6-494F-973C-45EF58A51DA9"); /// public string Author => "Natalia Portillo"; @@ -71,8 +72,12 @@ namespace Aaru.Filesystems if(partition.Start + hdrSector > imagePlugin.Info.Sectors) return false; - byte[] sector = imagePlugin.ReadSector(partition.Start + hdrSector); - Header hdr = Marshal.ByteArrayToStructureBigEndian
(sector); + ErrorNumber errno = imagePlugin.ReadSector(partition.Start + hdrSector, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return false; + + Header hdr = Marshal.ByteArrayToStructureBigEndian
(sector); AaruConsole.DebugWriteLine("Fossil plugin", "magic at 0x{0:X8} (expected 0x{1:X8})", hdr.magic, FOSSIL_HDR_MAGIC); @@ -93,8 +98,12 @@ namespace Aaru.Filesystems ulong hdrSector = HEADER_POS / imagePlugin.Info.SectorSize; - byte[] sector = imagePlugin.ReadSector(partition.Start + hdrSector); - Header hdr = Marshal.ByteArrayToStructureBigEndian
(sector); + ErrorNumber errno = imagePlugin.ReadSector(partition.Start + hdrSector, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return; + + Header hdr = Marshal.ByteArrayToStructureBigEndian
(sector); AaruConsole.DebugWriteLine("Fossil plugin", "magic at 0x{0:X8} (expected 0x{1:X8})", hdr.magic, FOSSIL_HDR_MAGIC); @@ -120,7 +129,7 @@ namespace Aaru.Filesystems if(sbLocation <= partition.End) { - sector = imagePlugin.ReadSector(sbLocation); + errno = imagePlugin.ReadSector(sbLocation, out sector); SuperBlock fsb = Marshal.ByteArrayToStructureBigEndian(sector); AaruConsole.DebugWriteLine("Fossil plugin", "magic 0x{0:X8} (expected 0x{1:X8})", fsb.magic, diff --git a/Aaru.Filesystems/HAMMER.cs b/Aaru.Filesystems/HAMMER.cs index e0644da30..b9bdc348e 100644 --- a/Aaru.Filesystems/HAMMER.cs +++ b/Aaru.Filesystems/HAMMER.cs @@ -35,6 +35,7 @@ using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; using System.Text; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Aaru.Helpers; using Schemas; @@ -63,7 +64,7 @@ namespace Aaru.Filesystems /// public string Name => "HAMMER Filesystem"; /// - public Guid Id => new Guid("91A188BF-5FD7-4677-BBD3-F59EBA9C864D"); + public Guid Id => new("91A188BF-5FD7-4677-BBD3-F59EBA9C864D"); /// public string Author => "Natalia Portillo"; @@ -78,7 +79,10 @@ namespace Aaru.Filesystems if(run + partition.Start >= partition.End) return false; - byte[] sbSector = imagePlugin.ReadSectors(partition.Start, run); + ErrorNumber errno = imagePlugin.ReadSectors(partition.Start, run, out byte[] sbSector); + + if(errno != ErrorNumber.NoError) + return false; ulong magic = BitConverter.ToUInt64(sbSector, 0); @@ -101,7 +105,10 @@ namespace Aaru.Filesystems if(HAMMER_VOLHDR_SIZE % imagePlugin.Info.SectorSize > 0) run++; - byte[] sbSector = imagePlugin.ReadSectors(partition.Start, run); + ErrorNumber errno = imagePlugin.ReadSectors(partition.Start, run, out byte[] sbSector); + + if(errno != ErrorNumber.NoError) + return; ulong magic = BitConverter.ToUInt64(sbSector, 0); diff --git a/Aaru.Filesystems/HPFS.cs b/Aaru.Filesystems/HPFS.cs index a1d046d55..41d8f98a6 100644 --- a/Aaru.Filesystems/HPFS.cs +++ b/Aaru.Filesystems/HPFS.cs @@ -35,6 +35,7 @@ using System.Runtime.InteropServices; using System.Text; using Aaru.Checksums; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Aaru.Helpers; using Schemas; @@ -54,7 +55,7 @@ namespace Aaru.Filesystems /// public string Name => "OS/2 High Performance File System"; /// - public Guid Id => new Guid("33513B2C-f590-4acb-8bf2-0b1d5e19dec5"); + public Guid Id => new("33513B2C-f590-4acb-8bf2-0b1d5e19dec5"); /// public string Author => "Natalia Portillo"; @@ -64,8 +65,12 @@ namespace Aaru.Filesystems if(16 + partition.Start >= partition.End) return false; - byte[] hpfsSbSector = - imagePlugin.ReadSector(16 + partition.Start); // Seek to superblock, on logical sector 16 + ErrorNumber errno = + imagePlugin.ReadSector(16 + partition.Start, + out byte[] hpfsSbSector); // Seek to superblock, on logical sector 16 + + if(errno != ErrorNumber.NoError) + return false; uint magic1 = BitConverter.ToUInt32(hpfsSbSector, 0x000); uint magic2 = BitConverter.ToUInt32(hpfsSbSector, 0x004); @@ -82,14 +87,24 @@ namespace Aaru.Filesystems var sb = new StringBuilder(); - byte[] hpfsBpbSector = - imagePlugin.ReadSector(0 + partition.Start); // Seek to BIOS parameter block, on logical sector 0 + ErrorNumber errno = + imagePlugin.ReadSector(0 + partition.Start, + out byte[] hpfsBpbSector); // Seek to BIOS parameter block, on logical sector 0 - byte[] hpfsSbSector = - imagePlugin.ReadSector(16 + partition.Start); // Seek to superblock, on logical sector 16 + if(errno != ErrorNumber.NoError) + return; - byte[] hpfsSpSector = - imagePlugin.ReadSector(17 + partition.Start); // Seek to spareblock, on logical sector 17 + errno = imagePlugin.ReadSector(16 + partition.Start, + out byte[] hpfsSbSector); // Seek to superblock, on logical sector 16 + + if(errno != ErrorNumber.NoError) + return; + + errno = imagePlugin.ReadSector(17 + partition.Start, + out byte[] hpfsSpSector); // Seek to spareblock, on logical sector 17 + + if(errno != ErrorNumber.NoError) + return; BiosParameterBlock bpb = Marshal.ByteArrayToStructureLittleEndian(hpfsBpbSector); diff --git a/Aaru.Filesystems/HPOFS/Info.cs b/Aaru.Filesystems/HPOFS/Info.cs index 479f23da4..8f47c98b3 100644 --- a/Aaru.Filesystems/HPOFS/Info.cs +++ b/Aaru.Filesystems/HPOFS/Info.cs @@ -34,6 +34,7 @@ using System.Linq; using System.Text; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Aaru.Console; using Aaru.Helpers; @@ -49,8 +50,12 @@ namespace Aaru.Filesystems if(16 + partition.Start >= partition.End) return false; - byte[] hpofsBpbSector = - imagePlugin.ReadSector(0 + partition.Start); // Seek to BIOS parameter block, on logical sector 0 + ErrorNumber errno = + imagePlugin.ReadSector(0 + partition.Start, + out byte[] hpofsBpbSector); // Seek to BIOS parameter block, on logical sector 0 + + if(errno != ErrorNumber.NoError) + return false; if(hpofsBpbSector.Length < 512) return false; @@ -69,14 +74,24 @@ namespace Aaru.Filesystems var sb = new StringBuilder(); - byte[] hpofsBpbSector = - imagePlugin.ReadSector(0 + partition.Start); // Seek to BIOS parameter block, on logical sector 0 + ErrorNumber errno = + imagePlugin.ReadSector(0 + partition.Start, + out byte[] hpofsBpbSector); // Seek to BIOS parameter block, on logical sector 0 - byte[] medInfoSector = - imagePlugin.ReadSector(13 + partition.Start); // Seek to media information block, on logical sector 13 + if(errno != ErrorNumber.NoError) + return; - byte[] volInfoSector = - imagePlugin.ReadSector(14 + partition.Start); // Seek to volume information block, on logical sector 14 + errno = imagePlugin.ReadSector(13 + partition.Start, + out byte[] medInfoSector); // Seek to media information block, on logical sector 13 + + if(errno != ErrorNumber.NoError) + return; + + errno = imagePlugin.ReadSector(14 + partition.Start, + out byte[] volInfoSector); // Seek to volume information block, on logical sector 14 + + if(errno != ErrorNumber.NoError) + return; BiosParameterBlock bpb = Marshal.ByteArrayToStructureLittleEndian(hpofsBpbSector); MediaInformationBlock mib = Marshal.ByteArrayToStructureBigEndian(medInfoSector); diff --git a/Aaru.Filesystems/ISO9660/Dir.cs b/Aaru.Filesystems/ISO9660/Dir.cs index 60f809ce4..c353bdb6f 100644 --- a/Aaru.Filesystems/ISO9660/Dir.cs +++ b/Aaru.Filesystems/ISO9660/Dir.cs @@ -845,7 +845,7 @@ namespace Aaru.Filesystems Marshal.ByteArrayToStructureLittleEndian(data, systemAreaOff, Marshal.SizeOf()); - byte[] childSector = ReadSector(cl.child_dir_lba); + ErrorNumber errno = ReadSector(cl.child_dir_lba, out byte[] childSector); DirectoryRecord childRecord = Marshal.ByteArrayToStructureLittleEndian(childSector); @@ -1054,7 +1054,7 @@ namespace Aaru.Filesystems foreach(PathTableEntryInternal tEntry in tableEntries) { - byte[] sector = ReadSector(tEntry.Extent); + ErrorNumber errno = ReadSector(tEntry.Extent, out byte[] sector); CdiDirectoryRecord record = Marshal.ByteArrayToStructureBigEndian(sector, tEntry.XattrLength, @@ -1104,7 +1104,7 @@ namespace Aaru.Filesystems foreach(PathTableEntryInternal tEntry in tableEntries) { - byte[] sector = ReadSector(tEntry.Extent); + ErrorNumber errno = ReadSector(tEntry.Extent, out byte[] sector); DirectoryRecord record = Marshal.ByteArrayToStructureLittleEndian(sector, tEntry.XattrLength, @@ -1154,7 +1154,7 @@ namespace Aaru.Filesystems foreach(PathTableEntryInternal tEntry in tableEntries) { - byte[] sector = ReadSector(tEntry.Extent); + ErrorNumber errno = ReadSector(tEntry.Extent, out byte[] sector); HighSierraDirectoryRecord record = Marshal.ByteArrayToStructureLittleEndian(sector, tEntry.XattrLength, diff --git a/Aaru.Filesystems/ISO9660/File.cs b/Aaru.Filesystems/ISO9660/File.cs index 8db8eb542..14067beba 100644 --- a/Aaru.Filesystems/ISO9660/File.cs +++ b/Aaru.Filesystems/ISO9660/File.cs @@ -525,9 +525,11 @@ namespace Aaru.Filesystems while(leftExtentSize > 0) { - byte[] sector = ReadSector(extents[i].extent + currentExtentSector, interleaved, fileNumber); + ErrorNumber errno = ReadSector(extents[i].extent + currentExtentSector, out byte[] sector, + interleaved, fileNumber); - if(sector is null) + if(errno != ErrorNumber.NoError || + sector is null) { currentExtentSector++; diff --git a/Aaru.Filesystems/ISO9660/Info.cs b/Aaru.Filesystems/ISO9660/Info.cs index 33140efb2..b84c3dc0a 100644 --- a/Aaru.Filesystems/ISO9660/Info.cs +++ b/Aaru.Filesystems/ISO9660/Info.cs @@ -36,6 +36,7 @@ using System.Collections.Generic; using System.Text; using Aaru.Checksums; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Aaru.Console; using Aaru.Decoders.Sega; @@ -58,7 +59,10 @@ namespace Aaru.Filesystems return false; // Read to Volume Descriptor - byte[] vdSector = imagePlugin.ReadSector(16 + partition.Start); + ErrorNumber errno = imagePlugin.ReadSector(16 + partition.Start, out byte[] vdSector); + + if(errno != ErrorNumber.NoError) + return false; int xaOff = 0; @@ -113,8 +117,12 @@ namespace Aaru.Filesystems ulong counter = 0; - byte[] vdSector = imagePlugin.ReadSector(16 + counter + partition.Start); - int xaOff = vdSector.Length == 2336 ? 8 : 0; + ErrorNumber errno = imagePlugin.ReadSector(16 + counter + partition.Start, out byte[] vdSector); + + if(errno != ErrorNumber.NoError) + return; + + int xaOff = vdSector.Length == 2336 ? 8 : 0; Array.Copy(vdSector, 0x009 + xaOff, hsMagic, 0, 5); bool highSierraInfo = Encoding.GetString(hsMagic) == HIGH_SIERRA_MAGIC; int hsOff = 0; @@ -132,7 +140,11 @@ namespace Aaru.Filesystems // Seek to Volume Descriptor AaruConsole.DebugWriteLine("ISO9660 plugin", "Reading sector {0}", 16 + counter + partition.Start); - byte[] vdSectorTmp = imagePlugin.ReadSector(16 + counter + partition.Start); + errno = imagePlugin.ReadSector(16 + counter + partition.Start, out byte[] vdSectorTmp); + + if(errno != ErrorNumber.NoError) + return; + vdSector = new byte[vdSectorTmp.Length - xaOff]; Array.Copy(vdSectorTmp, xaOff, vdSector, 0, vdSector.Length); @@ -289,12 +301,17 @@ namespace Aaru.Filesystems bool ziso = false; bool amiga = false; bool aaip = false; - List contareas = new List(); - List refareas = new List(); + List contareas = new(); + List refareas = new(); var suspInformation = new StringBuilder(); if(rootLocation + rootSize < imagePlugin.Info.Sectors) - rootDir = imagePlugin.ReadSectors(rootLocation, rootSize); + { + errno = imagePlugin.ReadSectors(rootLocation, rootSize, out rootDir); + + if(errno != ErrorNumber.NoError) + return; + } // Walk thru root directory to see system area extensions in use while(rootOff + Marshal.SizeOf() < rootDir.Length && @@ -455,8 +472,12 @@ namespace Aaru.Filesystems (highSierraInfo ? hsvd.Value.logical_block_size : pvd.Value.logical_block_size) > 0) caLen++; - byte[] caSectors = imagePlugin.ReadSectors(ca.block_be, caLen); - byte[] caData = new byte[ca.ca_length_be]; + errno = imagePlugin.ReadSectors(ca.block_be, caLen, out byte[] caSectors); + + if(errno != ErrorNumber.NoError) + return; + + byte[] caData = new byte[ca.ca_length_be]; Array.Copy(caSectors, ca.offset_be, caData, 0, ca.ca_length_be); int caOff = 0; @@ -525,10 +546,14 @@ namespace Aaru.Filesystems } } - byte[] ipbinSector = imagePlugin.ReadSector(0 + partition.Start); - CD.IPBin? segaCd = CD.DecodeIPBin(ipbinSector); - Saturn.IPBin? saturn = Saturn.DecodeIPBin(ipbinSector); - Dreamcast.IPBin? dreamcast = Dreamcast.DecodeIPBin(ipbinSector); + errno = imagePlugin.ReadSector(0 + partition.Start, out byte[] ipbinSector); + + if(errno != ErrorNumber.NoError) + return; + + CD.IPBin? segaCd = CD.DecodeIPBin(ipbinSector); + Saturn.IPBin? saturn = Saturn.DecodeIPBin(ipbinSector); + Dreamcast.IPBin? dreamcast = Dreamcast.DecodeIPBin(ipbinSector); string fsFormat; @@ -668,7 +693,10 @@ namespace Aaru.Filesystems if(torito != null) { - vdSector = imagePlugin.ReadSector(torito.Value.catalog_sector + partition.Start); + errno = imagePlugin.ReadSector(torito.Value.catalog_sector + partition.Start, out vdSector); + + if(errno != ErrorNumber.NoError) + return; int toritoOff = 0; @@ -696,10 +724,11 @@ namespace Aaru.Filesystems AaruConsole.DebugWriteLine("DEBUG (ISO9660 plugin)", "initialEntry.sector_count = {0}", initialEntry.sector_count); - byte[] bootImage = - initialEntry.load_rba + partition.Start + initialEntry.sector_count - 1 <= partition.End - ? imagePlugin.ReadSectors(initialEntry.load_rba + partition.Start, initialEntry.sector_count) - : null; + byte[] bootImage = null; + + if(initialEntry.load_rba + partition.Start + initialEntry.sector_count - 1 <= partition.End) + imagePlugin.ReadSectors(initialEntry.load_rba + partition.Start, initialEntry.sector_count, + out bootImage); isoMetadata.AppendLine("----------------------"); isoMetadata.AppendLine("EL TORITO INFORMATION:"); @@ -789,10 +818,11 @@ namespace Aaru.Filesystems if(sectionEntry.bootable == ElToritoIndicator.Bootable) { - bootImage = - sectionEntry.load_rba + partition.Start + sectionEntry.sector_count - 1 <= partition.End - ? imagePlugin.ReadSectors(sectionEntry.load_rba + partition.Start, - sectionEntry.sector_count) : null; + bootImage = null; + + if(sectionEntry.load_rba + partition.Start + sectionEntry.sector_count - 1 <= partition.End) + imagePlugin.ReadSectors(sectionEntry.load_rba + partition.Start, + sectionEntry.sector_count, out bootImage); isoMetadata.AppendFormat("\t\tBootable on {0}", sectionHeader.platform_id).AppendLine(); diff --git a/Aaru.Filesystems/ISO9660/Mode2.cs b/Aaru.Filesystems/ISO9660/Mode2.cs index 7b2e5e1e7..7c73fd59d 100644 --- a/Aaru.Filesystems/ISO9660/Mode2.cs +++ b/Aaru.Filesystems/ISO9660/Mode2.cs @@ -33,6 +33,7 @@ using System; using System.IO; +using Aaru.CommonTypes.Enums; using Aaru.Console; using Aaru.Decoders.CD; @@ -40,10 +41,11 @@ namespace Aaru.Filesystems { public sealed partial class ISO9660 { - byte[] ReadSector(ulong sector, bool interleaved = false, byte fileNumber = 0) + ErrorNumber ReadSector(ulong sector, out byte[] buffer, bool interleaved = false, byte fileNumber = 0) { - ulong realSector; - uint sectorCount; + ulong realSector; + uint sectorCount; + ErrorNumber errno = ErrorNumber.NoError; sectorCount = (uint)_blockSize / 2048; @@ -65,7 +67,7 @@ namespace Aaru.Filesystems } catch { - data = _image.ReadSector(realSector); + errno = _image.ReadSector(realSector, out data); } if(_debug) @@ -114,12 +116,18 @@ namespace Aaru.Filesystems } if(_blockSize == 2048) - return Sector.GetUserData(data, interleaved, fileNumber); + { + buffer = Sector.GetUserData(data, interleaved, fileNumber); + + return ErrorNumber.NoError; + } byte[] tmp = new byte[_blockSize]; Array.Copy(Sector.GetUserData(data, interleaved, fileNumber), (int)offset, tmp, 0, _blockSize); - return tmp; + buffer = tmp; + + return errno; } else { @@ -136,7 +144,7 @@ namespace Aaru.Filesystems } catch { - data = _image.ReadSector(dstSector); + errno = _image.ReadSector(dstSector, out data); } if(_debug) @@ -191,8 +199,9 @@ namespace Aaru.Filesystems byte[] tmp = new byte[_blockSize]; Array.Copy(Sector.GetUserData(ms.ToArray(), interleaved, fileNumber), 0, tmp, 0, _blockSize); + buffer = tmp; - return tmp; + return errno; } } } diff --git a/Aaru.Filesystems/ISO9660/Super.cs b/Aaru.Filesystems/ISO9660/Super.cs index 4bab4f382..55fa034c1 100644 --- a/Aaru.Filesystems/ISO9660/Super.cs +++ b/Aaru.Filesystems/ISO9660/Super.cs @@ -113,8 +113,12 @@ namespace Aaru.Filesystems ulong counter = 0; - byte[] vdSector = imagePlugin.ReadSector(16 + counter + partition.Start); - int xaOff = vdSector.Length == 2336 ? 8 : 0; + ErrorNumber errno = imagePlugin.ReadSector(16 + counter + partition.Start, out byte[] vdSector); + + if(errno != ErrorNumber.NoError) + return errno; + + int xaOff = vdSector.Length == 2336 ? 8 : 0; Array.Copy(vdSector, 0x009 + xaOff, hsMagic, 0, 5); _highSierra = Encoding.GetString(hsMagic) == HIGH_SIERRA_MAGIC; int hsOff = 0; @@ -135,7 +139,11 @@ namespace Aaru.Filesystems // Seek to Volume Descriptor AaruConsole.DebugWriteLine("ISO9660 plugin", "Reading sector {0}", 16 + counter + partition.Start); - byte[] vdSectorTmp = imagePlugin.ReadSector(16 + counter + partition.Start); + errno = imagePlugin.ReadSector(16 + counter + partition.Start, out byte[] vdSectorTmp); + + if(errno != ErrorNumber.NoError) + return errno; + vdSector = new byte[vdSectorTmp.Length - xaOff]; Array.Copy(vdSectorTmp, xaOff, vdSector, 0, vdSector.Length); @@ -354,7 +362,10 @@ namespace Aaru.Filesystems AaruConsole.DebugWriteLine("ISO9660 plugin", "Path table and PVD do not point to the same location for the root directory!"); - byte[] firstRootSector = ReadSector(rootLocation); + errno = ReadSector(rootLocation, out byte[] firstRootSector); + + if(errno != ErrorNumber.NoError) + return errno; bool pvdWrongRoot = false; @@ -384,7 +395,7 @@ namespace Aaru.Filesystems rootLocation = _pathTable[0].Extent; - firstRootSector = ReadSector(_pathTable[0].Extent); + errno = ReadSector(_pathTable[0].Extent, out firstRootSector); if(_highSierra) { @@ -418,7 +429,10 @@ namespace Aaru.Filesystems { rootLocation = _pathTable[0].Extent; - byte[] firstRootSector = ReadSector(rootLocation); + errno = ReadSector(rootLocation, out byte[] firstRootSector); + + if(errno != ErrorNumber.NoError) + return errno; CdiDirectoryRecord rootEntry = Marshal.ByteArrayToStructureBigEndian(firstRootSector); @@ -437,7 +451,10 @@ namespace Aaru.Filesystems { rootLocation = _pathTable[0].Extent; - byte[] firstRootSector = ReadSector(rootLocation); + errno = ReadSector(rootLocation, out byte[] firstRootSector); + + if(errno != ErrorNumber.NoError) + return errno; if(_highSierra) { @@ -466,10 +483,14 @@ namespace Aaru.Filesystems return ErrorNumber.InvalidArgument; } - byte[] ipbinSector = ReadSector(partition.Start); - CD.IPBin? segaCd = CD.DecodeIPBin(ipbinSector); - Saturn.IPBin? saturn = Saturn.DecodeIPBin(ipbinSector); - Dreamcast.IPBin? dreamcast = Dreamcast.DecodeIPBin(ipbinSector); + errno = ReadSector(partition.Start, out byte[] ipbinSector); + + if(errno != ErrorNumber.NoError) + return errno; + + CD.IPBin? segaCd = CD.DecodeIPBin(ipbinSector); + Saturn.IPBin? saturn = Saturn.DecodeIPBin(ipbinSector); + Dreamcast.IPBin? dreamcast = Dreamcast.DecodeIPBin(ipbinSector); if(_namespace == Namespace.Joliet || _namespace == Namespace.Rrip) diff --git a/Aaru.Filesystems/JFS.cs b/Aaru.Filesystems/JFS.cs index e413c9efc..b1ff282c4 100644 --- a/Aaru.Filesystems/JFS.cs +++ b/Aaru.Filesystems/JFS.cs @@ -35,6 +35,7 @@ using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; using System.Text; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Aaru.Helpers; using Schemas; @@ -58,7 +59,7 @@ namespace Aaru.Filesystems /// public string Name => "JFS Plugin"; /// - public Guid Id => new Guid("D3BE2A41-8F28-4055-94DC-BB6C72A0E9C4"); + public Guid Id => new("D3BE2A41-8F28-4055-94DC-BB6C72A0E9C4"); /// public string Author => "Natalia Portillo"; @@ -70,7 +71,10 @@ namespace Aaru.Filesystems if(partition.Start + bootSectors >= partition.End) return false; - byte[] sector = imagePlugin.ReadSector(partition.Start + bootSectors); + ErrorNumber errno = imagePlugin.ReadSector(partition.Start + bootSectors, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return false; if(sector.Length < 512) return false; @@ -86,9 +90,12 @@ namespace Aaru.Filesystems { Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15"); information = ""; - var sb = new StringBuilder(); - uint bootSectors = JFS_BOOT_BLOCKS_SIZE / imagePlugin.Info.SectorSize; - byte[] sector = imagePlugin.ReadSector(partition.Start + bootSectors); + var sb = new StringBuilder(); + uint bootSectors = JFS_BOOT_BLOCKS_SIZE / imagePlugin.Info.SectorSize; + ErrorNumber errno = imagePlugin.ReadSector(partition.Start + bootSectors, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return; if(sector.Length < 512) return; diff --git a/Aaru.Filesystems/LIF.cs b/Aaru.Filesystems/LIF.cs index 2f06a652b..c5b2090a3 100644 --- a/Aaru.Filesystems/LIF.cs +++ b/Aaru.Filesystems/LIF.cs @@ -34,6 +34,7 @@ using System; using System.Runtime.InteropServices; using System.Text; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Aaru.Console; using Aaru.Helpers; @@ -56,7 +57,7 @@ namespace Aaru.Filesystems /// public string Name => "HP Logical Interchange Format Plugin"; /// - public Guid Id => new Guid("41535647-77A5-477B-9206-DA727ACDC704"); + public Guid Id => new("41535647-77A5-477B-9206-DA727ACDC704"); /// public string Author => "Natalia Portillo"; @@ -66,8 +67,12 @@ namespace Aaru.Filesystems if(imagePlugin.Info.SectorSize < 256) return false; - byte[] sector = imagePlugin.ReadSector(partition.Start); - SystemBlock lifSb = Marshal.ByteArrayToStructureBigEndian(sector); + ErrorNumber errno = imagePlugin.ReadSector(partition.Start, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return false; + + SystemBlock lifSb = Marshal.ByteArrayToStructureBigEndian(sector); AaruConsole.DebugWriteLine("LIF plugin", "magic 0x{0:X8} (expected 0x{1:X8})", lifSb.magic, LIF_MAGIC); return lifSb.magic == LIF_MAGIC; @@ -83,8 +88,12 @@ namespace Aaru.Filesystems if(imagePlugin.Info.SectorSize < 256) return; - byte[] sector = imagePlugin.ReadSector(partition.Start); - SystemBlock lifSb = Marshal.ByteArrayToStructureBigEndian(sector); + ErrorNumber errno = imagePlugin.ReadSector(partition.Start, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return; + + SystemBlock lifSb = Marshal.ByteArrayToStructureBigEndian(sector); if(lifSb.magic != LIF_MAGIC) return; diff --git a/Aaru.Filesystems/LisaFS/Dir.cs b/Aaru.Filesystems/LisaFS/Dir.cs index 6c0a3544e..6887c6034 100644 --- a/Aaru.Filesystems/LisaFS/Dir.cs +++ b/Aaru.Filesystems/LisaFS/Dir.cs @@ -97,6 +97,8 @@ namespace Aaru.Filesystems.LisaFS /// Reads, interprets and caches the Catalog File ErrorNumber ReadCatalog() { + ErrorNumber errno; + if(!_mounted) return ErrorNumber.AccessDenied; @@ -180,7 +182,10 @@ namespace Aaru.Filesystems.LisaFS catTag.RelPage != 0) continue; - firstCatalogBlock = _device.ReadSectors(i, 4); + errno = _device.ReadSectors(i, 4, out firstCatalogBlock); + + if(errno != ErrorNumber.NoError) + return errno; break; } @@ -200,7 +205,12 @@ namespace Aaru.Filesystems.LisaFS if(prevTag.FileId != FILEID_CATALOG) return ErrorNumber.InvalidArgument; - firstCatalogBlock = _device.ReadSectors(prevCatalogPointer + _mddf.mddf_block + _volumePrefix, 4); + errno = _device.ReadSectors(prevCatalogPointer + _mddf.mddf_block + _volumePrefix, 4, + out firstCatalogBlock); + + if(errno != ErrorNumber.NoError) + return errno; + prevCatalogPointer = BigEndianBitConverter.ToUInt32(firstCatalogBlock, 0x7F6); } @@ -220,7 +230,12 @@ namespace Aaru.Filesystems.LisaFS if(nextTag.FileId != FILEID_CATALOG) return ErrorNumber.InvalidArgument; - byte[] nextCatalogBlock = _device.ReadSectors(nextCatalogPointer + _mddf.mddf_block + _volumePrefix, 4); + errno = _device.ReadSectors(nextCatalogPointer + _mddf.mddf_block + _volumePrefix, 4, + out byte[] nextCatalogBlock); + + if(errno != ErrorNumber.NoError) + return errno; + nextCatalogPointer = BigEndianBitConverter.ToUInt32(nextCatalogBlock, 0x7FA); catalogBlocks.Add(nextCatalogBlock); } diff --git a/Aaru.Filesystems/LisaFS/Extent.cs b/Aaru.Filesystems/LisaFS/Extent.cs index 3ffc3089d..2b0e90cc4 100644 --- a/Aaru.Filesystems/LisaFS/Extent.cs +++ b/Aaru.Filesystems/LisaFS/Extent.cs @@ -56,6 +56,7 @@ namespace Aaru.Filesystems.LisaFS ErrorNumber ReadExtentsFile(short fileId, out ExtentFile file) { file = new ExtentFile(); + ErrorNumber errno; if(!_mounted) return ErrorNumber.AccessDenied; @@ -113,7 +114,13 @@ namespace Aaru.Filesystems.LisaFS if(extTag.FileId != (short)(-1 * fileId)) return ErrorNumber.NoSuchFile; - byte[] sector = _mddf.fsversion == LISA_V1 ? _device.ReadSectors(ptr, 2) : _device.ReadSector(ptr); + byte[] sector; + + errno = _mddf.fsversion == LISA_V1 ? _device.ReadSectors(ptr, 2, out sector) + : _device.ReadSector(ptr, out sector); + + if(errno != ErrorNumber.NoError) + return errno; if(sector[0] >= 32 || sector[0] == 0) @@ -286,7 +293,11 @@ namespace Aaru.Filesystems.LisaFS return ErrorNumber.AccessDenied; // Searches the S-Records place using MDDF pointers - byte[] sectors = _device.ReadSectors(_mddf.srec_ptr + _mddf.mddf_block + _volumePrefix, _mddf.srec_len); + ErrorNumber errno = _device.ReadSectors(_mddf.srec_ptr + _mddf.mddf_block + _volumePrefix, _mddf.srec_len, + out byte[] sectors); + + if(errno != ErrorNumber.NoError) + return errno; // Each entry takes 14 bytes _srecords = new SRecord[sectors.Length / 14]; diff --git a/Aaru.Filesystems/LisaFS/File.cs b/Aaru.Filesystems/LisaFS/File.cs index bcdc5c20c..85411f22a 100644 --- a/Aaru.Filesystems/LisaFS/File.cs +++ b/Aaru.Filesystems/LisaFS/File.cs @@ -192,6 +192,7 @@ namespace Aaru.Filesystems.LisaFS ErrorNumber ReadSystemFile(short fileId, out byte[] buf, bool tags) { buf = null; + ErrorNumber errno; if(!_mounted || !_debug) @@ -212,7 +213,12 @@ namespace Aaru.Filesystems.LisaFS if(fileId == FILEID_SRECORD) if(!tags) { - buf = _device.ReadSectors(_mddf.mddf_block + _volumePrefix + _mddf.srec_ptr, _mddf.srec_len); + errno = _device.ReadSectors(_mddf.mddf_block + _volumePrefix + _mddf.srec_ptr, _mddf.srec_len, + out buf); + + if(errno != ErrorNumber.NoError) + return errno; + _systemFileCache.Add(fileId, buf); return ErrorNumber.NoError; @@ -249,7 +255,17 @@ namespace Aaru.Filesystems.LisaFS if(sysTag.FileId != fileId) continue; - byte[] sector = !tags ? _device.ReadSector(i) : _device.ReadSectorTag(i, SectorTagType.AppleSectorTag); + byte[] sector; + + if(!tags) + { + errno = _device.ReadSector(i, out sector); + + if(errno != ErrorNumber.NoError) + continue; + } + else + sector = _device.ReadSectorTag(i, SectorTagType.AppleSectorTag); // Relative block for $Loader starts at $Boot block if(sysTag.FileId == FILEID_LOADER_SIGNED) @@ -367,6 +383,7 @@ namespace Aaru.Filesystems.LisaFS ErrorNumber ReadFile(short fileId, out byte[] buf, bool tags) { buf = null; + ErrorNumber errno; if(!_mounted) return ErrorNumber.AccessDenied; @@ -402,8 +419,13 @@ namespace Aaru.Filesystems.LisaFS byte[] sector; if(!tags) - sector = _device.ReadSectors((ulong)file.extents[i].start + _mddf.mddf_block + _volumePrefix, - (uint)file.extents[i].length); + { + errno = _device.ReadSectors((ulong)file.extents[i].start + _mddf.mddf_block + _volumePrefix, + (uint)file.extents[i].length, out sector); + + if(errno != ErrorNumber.NoError) + return errno; + } else sector = _device.ReadSectorsTag((ulong)file.extents[i].start + _mddf.mddf_block + _volumePrefix, (uint)file.extents[i].length, SectorTagType.AppleSectorTag); diff --git a/Aaru.Filesystems/LisaFS/Info.cs b/Aaru.Filesystems/LisaFS/Info.cs index ad30394c2..d6571eec0 100644 --- a/Aaru.Filesystems/LisaFS/Info.cs +++ b/Aaru.Filesystems/LisaFS/Info.cs @@ -49,6 +49,8 @@ namespace Aaru.Filesystems.LisaFS /// public bool Identify(IMediaImage imagePlugin, Partition partition) { + ErrorNumber errno; + try { if(imagePlugin.Info.ReadableSectorTags?.Contains(SectorTagType.AppleSectorTag) != true) @@ -75,7 +77,10 @@ namespace Aaru.Filesystems.LisaFS if(searchTag.FileId != FILEID_MDDF) continue; - byte[] sector = imagePlugin.ReadSector((ulong)i); + errno = imagePlugin.ReadSector((ulong)i, out byte[] sector); + + if(errno != ErrorNumber.NoError) + continue; var infoMddf = new MDDF { @@ -137,7 +142,8 @@ namespace Aaru.Filesystems.LisaFS { Encoding = new LisaRoman(); information = ""; - var sb = new StringBuilder(); + var sb = new StringBuilder(); + ErrorNumber errno; try { @@ -165,7 +171,11 @@ namespace Aaru.Filesystems.LisaFS if(searchTag.FileId != FILEID_MDDF) continue; - byte[] sector = imagePlugin.ReadSector((ulong)i); + errno = imagePlugin.ReadSector((ulong)i, out byte[] sector); + + if(errno != ErrorNumber.NoError) + continue; + var infoMddf = new MDDF(); byte[] pString = new byte[33]; diff --git a/Aaru.Filesystems/LisaFS/Super.cs b/Aaru.Filesystems/LisaFS/Super.cs index d5c9696d2..f8a192c0f 100644 --- a/Aaru.Filesystems/LisaFS/Super.cs +++ b/Aaru.Filesystems/LisaFS/Super.cs @@ -93,7 +93,11 @@ namespace Aaru.Filesystems.LisaFS _devTagSize = _device.ReadSectorTag(i, SectorTagType.AppleSectorTag).Length; - byte[] sector = _device.ReadSector(i); + ErrorNumber errno = _device.ReadSector(i, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return errno; + _mddf = new MDDF(); byte[] pString = new byte[33]; diff --git a/Aaru.Filesystems/Locus.cs b/Aaru.Filesystems/Locus.cs index 012ebe109..9c5434cc4 100644 --- a/Aaru.Filesystems/Locus.cs +++ b/Aaru.Filesystems/Locus.cs @@ -35,6 +35,7 @@ using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; using System.Text; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Aaru.Console; using Aaru.Helpers; @@ -88,7 +89,7 @@ namespace Aaru.Filesystems /// public string Name => "Locus Filesystem Plugin"; /// - public Guid Id => new Guid("1A70B30A-437D-479A-88E1-D0C9C1797FF4"); + public Guid Id => new("1A70B30A-437D-479A-88E1-D0C9C1797FF4"); /// public string Author => "Natalia Portillo"; @@ -108,7 +109,10 @@ namespace Aaru.Filesystems if(partition.Start + location + sbSize >= imagePlugin.Info.Sectors) break; - byte[] sector = imagePlugin.ReadSectors(partition.Start + location, sbSize); + ErrorNumber errno = imagePlugin.ReadSectors(partition.Start + location, sbSize, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return false; if(sector.Length < Marshal.SizeOf()) return false; @@ -147,7 +151,10 @@ namespace Aaru.Filesystems if(Marshal.SizeOf() % imagePlugin.Info.SectorSize != 0) sbSize++; - sector = imagePlugin.ReadSectors(partition.Start + location, sbSize); + ErrorNumber errno = imagePlugin.ReadSectors(partition.Start + location, sbSize, out sector); + + if(errno != ErrorNumber.NoError) + continue; if(sector.Length < Marshal.SizeOf()) return; diff --git a/Aaru.Filesystems/MicroDOS.cs b/Aaru.Filesystems/MicroDOS.cs index 511280662..368db8694 100644 --- a/Aaru.Filesystems/MicroDOS.cs +++ b/Aaru.Filesystems/MicroDOS.cs @@ -34,6 +34,7 @@ using System; using System.Runtime.InteropServices; using System.Text; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Schemas; using Marshal = Aaru.Helpers.Marshal; @@ -60,7 +61,7 @@ namespace Aaru.Filesystems /// public string Name => "MicroDOS file system"; /// - public Guid Id => new Guid("9F9A364A-1A27-48A3-B730-7A7122000324"); + public Guid Id => new("9F9A364A-1A27-48A3-B730-7A7122000324"); /// public string Author => "Natalia Portillo"; @@ -73,7 +74,10 @@ namespace Aaru.Filesystems if(imagePlugin.Info.SectorSize < 512) return false; - byte[] bk0 = imagePlugin.ReadSector(0 + partition.Start); + ErrorNumber errno = imagePlugin.ReadSector(0 + partition.Start, out byte[] bk0); + + if(errno != ErrorNumber.NoError) + return false; Block0 block0 = Marshal.ByteArrayToStructureLittleEndian(bk0); @@ -89,7 +93,10 @@ namespace Aaru.Filesystems var sb = new StringBuilder(); - byte[] bk0 = imagePlugin.ReadSector(0 + partition.Start); + ErrorNumber errno = imagePlugin.ReadSector(0 + partition.Start, out byte[] bk0); + + if(errno != ErrorNumber.NoError) + return; Block0 block0 = Marshal.ByteArrayToStructureLittleEndian(bk0); diff --git a/Aaru.Filesystems/MinixFS.cs b/Aaru.Filesystems/MinixFS.cs index bc3dbcb4c..371d02666 100644 --- a/Aaru.Filesystems/MinixFS.cs +++ b/Aaru.Filesystems/MinixFS.cs @@ -76,7 +76,7 @@ namespace Aaru.Filesystems /// public string Name => "Minix Filesystem"; /// - public Guid Id => new Guid("FE248C3B-B727-4AE5-A39F-79EA9A07D4B3"); + public Guid Id => new("FE248C3B-B727-4AE5-A39F-79EA9A07D4B3"); /// public string Author => "Natalia Portillo"; @@ -95,7 +95,10 @@ namespace Aaru.Filesystems if(sector + partition.Start >= partition.End) return false; - byte[] minixSbSector = imagePlugin.ReadSector(sector + partition.Start); + ErrorNumber errno = imagePlugin.ReadSector(sector + partition.Start, out byte[] minixSbSector); + + if(errno != ErrorNumber.NoError) + return false; // Optical media if(offset > 0) @@ -141,10 +144,13 @@ namespace Aaru.Filesystems offset = 0x400; } - bool minix3 = false; - int filenamesize; - string minixVersion; - byte[] minixSbSector = imagePlugin.ReadSector(sector + partition.Start); + bool minix3 = false; + int filenamesize; + string minixVersion; + ErrorNumber errno = imagePlugin.ReadSector(sector + partition.Start, out byte[] minixSbSector); + + if(errno != ErrorNumber.NoError) + return; // Optical media if(offset > 0) diff --git a/Aaru.Filesystems/NILFS2.cs b/Aaru.Filesystems/NILFS2.cs index 0532e81d5..3a80b85f1 100644 --- a/Aaru.Filesystems/NILFS2.cs +++ b/Aaru.Filesystems/NILFS2.cs @@ -34,6 +34,7 @@ using System; using System.Runtime.InteropServices; using System.Text; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Aaru.Helpers; using Schemas; @@ -57,7 +58,7 @@ namespace Aaru.Filesystems /// public string Name => "NILFS2 Plugin"; /// - public Guid Id => new Guid("35224226-C5CC-48B5-8FFD-3781E91E86B6"); + public Guid Id => new("35224226-C5CC-48B5-8FFD-3781E91E86B6"); /// public string Author => "Natalia Portillo"; @@ -80,7 +81,10 @@ namespace Aaru.Filesystems if(partition.Start + sbAddr + sbSize >= partition.End) return false; - byte[] sector = imagePlugin.ReadSectors(partition.Start + sbAddr, sbSize); + ErrorNumber errno = imagePlugin.ReadSectors(partition.Start + sbAddr, sbSize, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return false; if(sector.Length < Marshal.SizeOf()) return false; @@ -110,7 +114,10 @@ namespace Aaru.Filesystems if(Marshal.SizeOf() % imagePlugin.Info.SectorSize != 0) sbSize++; - byte[] sector = imagePlugin.ReadSectors(partition.Start + sbAddr, sbSize); + ErrorNumber errno = imagePlugin.ReadSectors(partition.Start + sbAddr, sbSize, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return; if(sector.Length < Marshal.SizeOf()) return; diff --git a/Aaru.Filesystems/NTFS.cs b/Aaru.Filesystems/NTFS.cs index 3ae8c8d56..aafa9e2c9 100644 --- a/Aaru.Filesystems/NTFS.cs +++ b/Aaru.Filesystems/NTFS.cs @@ -35,6 +35,7 @@ using System.Runtime.InteropServices; using System.Text; using Aaru.Checksums; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Aaru.Helpers; using Schemas; @@ -54,7 +55,7 @@ namespace Aaru.Filesystems /// public string Name => "New Technology File System (NTFS)"; /// - public Guid Id => new Guid("33513B2C-1e6d-4d21-a660-0bbc789c3871"); + public Guid Id => new("33513B2C-1e6d-4d21-a660-0bbc789c3871"); /// public string Author => "Natalia Portillo"; @@ -66,7 +67,10 @@ namespace Aaru.Filesystems byte[] eigthBytes = new byte[8]; - byte[] ntfsBpb = imagePlugin.ReadSector(0 + partition.Start); + ErrorNumber errno = imagePlugin.ReadSector(0 + partition.Start, out byte[] ntfsBpb); + + if(errno != ErrorNumber.NoError) + return false; Array.Copy(ntfsBpb, 0x003, eigthBytes, 0, 8); string oemName = StringHandlers.CToString(eigthBytes); @@ -96,7 +100,10 @@ namespace Aaru.Filesystems var sb = new StringBuilder(); - byte[] ntfsBpb = imagePlugin.ReadSector(0 + partition.Start); + ErrorNumber errno = imagePlugin.ReadSector(0 + partition.Start, out byte[] ntfsBpb); + + if(errno != ErrorNumber.NoError) + return; BiosParameterBlock ntfsBb = Marshal.ByteArrayToStructureLittleEndian(ntfsBpb); diff --git a/Aaru.Filesystems/Nintendo.cs b/Aaru.Filesystems/Nintendo.cs index d07c7f4fb..e380fd83d 100644 --- a/Aaru.Filesystems/Nintendo.cs +++ b/Aaru.Filesystems/Nintendo.cs @@ -33,6 +33,7 @@ using System; using System.Text; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Aaru.Console; using Aaru.Helpers; @@ -51,7 +52,7 @@ namespace Aaru.Filesystems /// public string Name => "Nintendo optical filesystems"; /// - public Guid Id => new Guid("4675fcb4-4418-4288-9e4a-33d6a4ac1126"); + public Guid Id => new("4675fcb4-4418-4288-9e4a-33d6a4ac1126"); /// public string Author => "Natalia Portillo"; @@ -64,7 +65,10 @@ namespace Aaru.Filesystems if(imagePlugin.Info.Sectors * imagePlugin.Info.SectorSize < 0x50000) return false; - byte[] header = imagePlugin.ReadSectors(0, 0x50000 / imagePlugin.Info.SectorSize); + ErrorNumber errno = imagePlugin.ReadSectors(0, 0x50000 / imagePlugin.Info.SectorSize, out byte[] header); + + if(errno != ErrorNumber.NoError) + return false; uint magicGc = BigEndianBitConverter.ToUInt32(header, 0x1C); uint magicWii = BigEndianBitConverter.ToUInt32(header, 0x18); @@ -83,7 +87,10 @@ namespace Aaru.Filesystems var fields = new NintendoFields(); - byte[] header = imagePlugin.ReadSectors(0, 0x50000 / imagePlugin.Info.SectorSize); + ErrorNumber errno = imagePlugin.ReadSectors(0, 0x50000 / imagePlugin.Info.SectorSize, out byte[] header); + + if(errno != ErrorNumber.NoError) + return; bool wii = false; diff --git a/Aaru.Filesystems/ODS.cs b/Aaru.Filesystems/ODS.cs index 1135b8e9f..463e4049e 100644 --- a/Aaru.Filesystems/ODS.cs +++ b/Aaru.Filesystems/ODS.cs @@ -63,7 +63,7 @@ namespace Aaru.Filesystems /// public string Name => "Files-11 On-Disk Structure"; /// - public Guid Id => new Guid("de20633c-8021-4384-aeb0-83b0df14491f"); + public Guid Id => new("de20633c-8021-4384-aeb0-83b0df14491f"); /// public string Author => "Natalia Portillo"; @@ -76,8 +76,11 @@ namespace Aaru.Filesystems if(imagePlugin.Info.SectorSize < 512) return false; - byte[] magicB = new byte[12]; - byte[] hbSector = imagePlugin.ReadSector(1 + partition.Start); + byte[] magicB = new byte[12]; + ErrorNumber errno = imagePlugin.ReadSector(1 + partition.Start, out byte[] hbSector); + + if(errno != ErrorNumber.NoError) + return false; Array.Copy(hbSector, 0x1F0, magicB, 0, 12); string magic = Encoding.ASCII.GetString(magicB); @@ -95,7 +98,10 @@ namespace Aaru.Filesystems if(hbSector.Length < 0x400) return false; - hbSector = imagePlugin.ReadSector(partition.Start); + errno = imagePlugin.ReadSector(partition.Start, out hbSector); + + if(errno != ErrorNumber.NoError) + return false; Array.Copy(hbSector, 0x3F0, magicB, 0, 12); magic = Encoding.ASCII.GetString(magicB); @@ -114,7 +120,10 @@ namespace Aaru.Filesystems var sb = new StringBuilder(); - byte[] hbSector = imagePlugin.ReadSector(1 + partition.Start); + ErrorNumber errno = imagePlugin.ReadSector(1 + partition.Start, out byte[] hbSector); + + if(errno != ErrorNumber.NoError) + return; HomeBlock homeblock = Marshal.ByteArrayToStructureLittleEndian(hbSector); @@ -126,7 +135,11 @@ namespace Aaru.Filesystems if(hbSector.Length < 0x400) return; - byte[] tmp = imagePlugin.ReadSector(partition.Start); + errno = imagePlugin.ReadSector(partition.Start, out byte[] tmp); + + if(errno != ErrorNumber.NoError) + return; + hbSector = new byte[0x200]; Array.Copy(tmp, 0x200, hbSector, 0, 0x200); diff --git a/Aaru.Filesystems/Opera/Dir.cs b/Aaru.Filesystems/Opera/Dir.cs index c92a6106d..54f4a2080 100644 --- a/Aaru.Filesystems/Opera/Dir.cs +++ b/Aaru.Filesystems/Opera/Dir.cs @@ -125,7 +125,12 @@ namespace Aaru.Filesystems do { - byte[] data = _image.ReadSectors((ulong)(nextBlock * _volumeBlockSizeRatio), _volumeBlockSizeRatio); + ErrorNumber errno = _image.ReadSectors((ulong)(nextBlock * _volumeBlockSizeRatio), + _volumeBlockSizeRatio, out byte[] data); + + if(errno != ErrorNumber.NoError) + break; + header = Marshal.ByteArrayToStructureBigEndian(data); nextBlock = header.next_block + firstBlock; diff --git a/Aaru.Filesystems/Opera/File.cs b/Aaru.Filesystems/Opera/File.cs index 6a92ff73d..dfa8f3404 100644 --- a/Aaru.Filesystems/Opera/File.cs +++ b/Aaru.Filesystems/Opera/File.cs @@ -130,8 +130,11 @@ namespace Aaru.Filesystems else fileBlockSizeRatio = entry.Entry.block_size / _image.Info.SectorSize; - byte[] buffer = _image.ReadSectors((ulong)(entry.Pointers[0] + (firstBlock * fileBlockSizeRatio)), - (uint)(sizeInBlocks * fileBlockSizeRatio)); + ErrorNumber errno = _image.ReadSectors((ulong)(entry.Pointers[0] + (firstBlock * fileBlockSizeRatio)), + (uint)(sizeInBlocks * fileBlockSizeRatio), out byte[] buffer); + + if(errno != ErrorNumber.NoError) + return errno; buf = new byte[size]; Array.Copy(buffer, offsetInBlock, buf, 0, size); diff --git a/Aaru.Filesystems/Opera/Info.cs b/Aaru.Filesystems/Opera/Info.cs index 15691d10a..30245278d 100644 --- a/Aaru.Filesystems/Opera/Info.cs +++ b/Aaru.Filesystems/Opera/Info.cs @@ -33,6 +33,7 @@ using System; using System.Text; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Aaru.Helpers; using Schemas; @@ -47,7 +48,10 @@ namespace Aaru.Filesystems if(2 + partition.Start >= partition.End) return false; - byte[] sbSector = imagePlugin.ReadSector(0 + partition.Start); + ErrorNumber errno = imagePlugin.ReadSector(0 + partition.Start, out byte[] sbSector); + + if(errno != ErrorNumber.NoError) + return false; byte[] syncBytes = new byte[5]; @@ -71,7 +75,10 @@ namespace Aaru.Filesystems information = ""; var superBlockMetadata = new StringBuilder(); - byte[] sbSector = imagePlugin.ReadSector(0 + partition.Start); + ErrorNumber errno = imagePlugin.ReadSector(0 + partition.Start, out byte[] sbSector); + + if(errno != ErrorNumber.NoError) + return; SuperBlock sb = Marshal.ByteArrayToStructureBigEndian(sbSector); diff --git a/Aaru.Filesystems/Opera/Super.cs b/Aaru.Filesystems/Opera/Super.cs index b0df1e976..e33c45be5 100644 --- a/Aaru.Filesystems/Opera/Super.cs +++ b/Aaru.Filesystems/Opera/Super.cs @@ -55,7 +55,10 @@ namespace Aaru.Filesystems if(options.TryGetValue("debug", out string debugString)) bool.TryParse(debugString, out _debug); - byte[] sbSector = imagePlugin.ReadSector(0 + partition.Start); + ErrorNumber errno = imagePlugin.ReadSector(0 + partition.Start, out byte[] sbSector); + + if(errno != ErrorNumber.NoError) + return errno; SuperBlock sb = Marshal.ByteArrayToStructureBigEndian(sbSector); diff --git a/Aaru.Filesystems/PCEngine.cs b/Aaru.Filesystems/PCEngine.cs index 750371fae..e4ec17399 100644 --- a/Aaru.Filesystems/PCEngine.cs +++ b/Aaru.Filesystems/PCEngine.cs @@ -33,6 +33,7 @@ using System; using System.Text; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Schemas; @@ -49,7 +50,7 @@ namespace Aaru.Filesystems /// public string Name => "PC Engine CD Plugin"; /// - public Guid Id => new Guid("e5ee6d7c-90fa-49bd-ac89-14ef750b8af3"); + public Guid Id => new("e5ee6d7c-90fa-49bd-ac89-14ef750b8af3"); /// public string Author => "Natalia Portillo"; @@ -59,8 +60,11 @@ namespace Aaru.Filesystems if(2 + partition.Start >= partition.End) return false; - byte[] systemDescriptor = new byte[23]; - byte[] sector = imagePlugin.ReadSector(1 + partition.Start); + byte[] systemDescriptor = new byte[23]; + ErrorNumber errno = imagePlugin.ReadSector(1 + partition.Start, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return false; Array.Copy(sector, 0x20, systemDescriptor, 0, 23); diff --git a/Aaru.Filesystems/PCFX.cs b/Aaru.Filesystems/PCFX.cs index d7769c2bb..25c0ec89f 100644 --- a/Aaru.Filesystems/PCFX.cs +++ b/Aaru.Filesystems/PCFX.cs @@ -55,7 +55,7 @@ namespace Aaru.Filesystems /// public string Name => "PC-FX Plugin"; /// - public Guid Id => new Guid("8BC27CCE-D9E9-48F8-BA93-C66A86EB565A"); + public Guid Id => new("8BC27CCE-D9E9-48F8-BA93-C66A86EB565A"); /// public string Author => "Natalia Portillo"; @@ -66,7 +66,10 @@ namespace Aaru.Filesystems imagePlugin.Info.XmlMediaType != XmlMediaType.OpticalDisc) return false; - byte[] sector = imagePlugin.ReadSectors(partition.Start, 2); + ErrorNumber errno = imagePlugin.ReadSectors(partition.Start, 2, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return false; var encoding = Encoding.GetEncoding("shift_jis"); @@ -81,7 +84,11 @@ namespace Aaru.Filesystems Encoding = Encoding.GetEncoding("shift_jis"); information = ""; - byte[] sector = imagePlugin.ReadSectors(partition.Start, 2); + ErrorNumber errno = imagePlugin.ReadSectors(partition.Start, 2, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return; + Header header = Marshal.ByteArrayToStructureLittleEndian
(sector); string date; diff --git a/Aaru.Filesystems/PFS.cs b/Aaru.Filesystems/PFS.cs index b3496b4ba..f4920c76b 100644 --- a/Aaru.Filesystems/PFS.cs +++ b/Aaru.Filesystems/PFS.cs @@ -34,6 +34,7 @@ using System; using System.Runtime.InteropServices; using System.Text; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Aaru.Helpers; using Schemas; @@ -65,7 +66,7 @@ namespace Aaru.Filesystems /// public string Name => "Professional File System"; /// - public Guid Id => new Guid("68DE769E-D957-406A-8AE4-3781CA8CDA77"); + public Guid Id => new("68DE769E-D957-406A-8AE4-3781CA8CDA77"); /// public string Author => "Natalia Portillo"; @@ -75,7 +76,10 @@ namespace Aaru.Filesystems if(partition.Length < 3) return false; - byte[] sector = imagePlugin.ReadSector(2 + partition.Start); + ErrorNumber errno = imagePlugin.ReadSector(2 + partition.Start, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return false; uint magic = BigEndianBitConverter.ToUInt32(sector, 0x00); @@ -87,9 +91,14 @@ namespace Aaru.Filesystems public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information, Encoding encoding) { - Encoding = encoding ?? Encoding.GetEncoding("iso-8859-1"); - byte[] rootBlockSector = imagePlugin.ReadSector(2 + partition.Start); - RootBlock rootBlock = Marshal.ByteArrayToStructureBigEndian(rootBlockSector); + information = ""; + Encoding = encoding ?? Encoding.GetEncoding("iso-8859-1"); + ErrorNumber errno = imagePlugin.ReadSector(2 + partition.Start, out byte[] rootBlockSector); + + if(errno != ErrorNumber.NoError) + return; + + RootBlock rootBlock = Marshal.ByteArrayToStructureBigEndian(rootBlockSector); var sbInformation = new StringBuilder(); XmlFsType = new FileSystemType(); diff --git a/Aaru.Filesystems/ProDOS.cs b/Aaru.Filesystems/ProDOS.cs index 4a1b44e27..fd45c1c61 100644 --- a/Aaru.Filesystems/ProDOS.cs +++ b/Aaru.Filesystems/ProDOS.cs @@ -35,6 +35,7 @@ using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Text; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Aaru.Console; using Claunia.Encoding; @@ -90,7 +91,7 @@ namespace Aaru.Filesystems /// public string Name => "Apple ProDOS filesystem"; /// - public Guid Id => new Guid("43874265-7B8A-4739-BCF7-07F80D5932BF"); + public Guid Id => new("43874265-7B8A-4739-BCF7-07F80D5932BF"); /// public string Author => "Natalia Portillo"; @@ -103,14 +104,19 @@ namespace Aaru.Filesystems uint multiplier = (uint)(imagePlugin.Info.SectorSize == 256 ? 2 : 1); // Blocks 0 and 1 are boot code - byte[] rootDirectoryKeyBlock = imagePlugin.ReadSectors((2 * multiplier) + partition.Start, multiplier); - bool apmFromHddOnCd = false; + ErrorNumber errno = imagePlugin.ReadSectors((2 * multiplier) + partition.Start, multiplier, + out byte[] rootDirectoryKeyBlock); + + bool apmFromHddOnCd = false; if(imagePlugin.Info.SectorSize == 2352 || imagePlugin.Info.SectorSize == 2448 || imagePlugin.Info.SectorSize == 2048) { - byte[] tmp = imagePlugin.ReadSectors(partition.Start, 2); + errno = imagePlugin.ReadSectors(partition.Start, 2, out byte[] tmp); + + if(errno != ErrorNumber.NoError) + return false; foreach(int offset in new[] { @@ -171,12 +177,17 @@ namespace Aaru.Filesystems public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information, Encoding encoding) { - Encoding = encoding ?? new Apple2c(); + Encoding = encoding ?? new Apple2c(); + information = ""; var sbInformation = new StringBuilder(); uint multiplier = (uint)(imagePlugin.Info.SectorSize == 256 ? 2 : 1); // Blocks 0 and 1 are boot code - byte[] rootDirectoryKeyBlockBytes = imagePlugin.ReadSectors((2 * multiplier) + partition.Start, multiplier); + ErrorNumber errno = imagePlugin.ReadSectors((2 * multiplier) + partition.Start, multiplier, + out byte[] rootDirectoryKeyBlockBytes); + + if(errno != ErrorNumber.NoError) + return; bool apmFromHddOnCd = false; @@ -184,7 +195,10 @@ namespace Aaru.Filesystems imagePlugin.Info.SectorSize == 2448 || imagePlugin.Info.SectorSize == 2048) { - byte[] tmp = imagePlugin.ReadSectors(partition.Start, 2); + errno = imagePlugin.ReadSectors(partition.Start, 2, out byte[] tmp); + + if(errno != ErrorNumber.NoError) + return; foreach(int offset in new[] { diff --git a/Aaru.Filesystems/QNX4.cs b/Aaru.Filesystems/QNX4.cs index 2aad2b1ef..fce5163fe 100644 --- a/Aaru.Filesystems/QNX4.cs +++ b/Aaru.Filesystems/QNX4.cs @@ -36,6 +36,7 @@ using System.Linq; using System.Runtime.InteropServices; using System.Text; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Aaru.Helpers; using Schemas; @@ -60,7 +61,7 @@ namespace Aaru.Filesystems /// public string Name => "QNX4 Plugin"; /// - public Guid Id => new Guid("E73A63FA-B5B0-48BF-BF82-DA5F0A8170D2"); + public Guid Id => new("E73A63FA-B5B0-48BF-BF82-DA5F0A8170D2"); /// public string Author => "Natalia Portillo"; @@ -70,7 +71,10 @@ namespace Aaru.Filesystems if(partition.Start + 1 >= imagePlugin.Info.Sectors) return false; - byte[] sector = imagePlugin.ReadSector(partition.Start + 1); + ErrorNumber errno = imagePlugin.ReadSector(partition.Start + 1, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return false; if(sector.Length < 512) return false; @@ -111,7 +115,10 @@ namespace Aaru.Filesystems { Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15"); information = ""; - byte[] sector = imagePlugin.ReadSector(partition.Start + 1); + ErrorNumber errno = imagePlugin.ReadSector(partition.Start + 1, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return; if(sector.Length < 512) return; diff --git a/Aaru.Filesystems/QNX6.cs b/Aaru.Filesystems/QNX6.cs index e717999cf..a8748fbea 100644 --- a/Aaru.Filesystems/QNX6.cs +++ b/Aaru.Filesystems/QNX6.cs @@ -34,6 +34,7 @@ using System; using System.Runtime.InteropServices; using System.Text; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Aaru.Helpers; using Schemas; @@ -56,7 +57,7 @@ namespace Aaru.Filesystems /// public string Name => "QNX6 Plugin"; /// - public Guid Id => new Guid("3E610EA2-4D08-4D70-8947-830CD4C74FC0"); + public Guid Id => new("3E610EA2-4D08-4D70-8947-830CD4C74FC0"); /// public string Author => "Natalia Portillo"; @@ -69,8 +70,15 @@ namespace Aaru.Filesystems if(partition.Start + bootSectors + sectors >= partition.End) return false; - byte[] audiSector = imagePlugin.ReadSectors(partition.Start, sectors); - byte[] sector = imagePlugin.ReadSectors(partition.Start + bootSectors, sectors); + ErrorNumber errno = imagePlugin.ReadSectors(partition.Start, sectors, out byte[] audiSector); + + if(errno != ErrorNumber.NoError) + return false; + + errno = imagePlugin.ReadSectors(partition.Start + bootSectors, sectors, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return false; if(sector.Length < QNX6_SUPER_BLOCK_SIZE) return false; @@ -92,8 +100,15 @@ namespace Aaru.Filesystems uint sectors = QNX6_SUPER_BLOCK_SIZE / imagePlugin.Info.SectorSize; uint bootSectors = QNX6_BOOT_BLOCKS_SIZE / imagePlugin.Info.SectorSize; - byte[] audiSector = imagePlugin.ReadSectors(partition.Start, sectors); - byte[] sector = imagePlugin.ReadSectors(partition.Start + bootSectors, sectors); + ErrorNumber errno = imagePlugin.ReadSectors(partition.Start, sectors, out byte[] audiSector); + + if(errno != ErrorNumber.NoError) + return; + + errno = imagePlugin.ReadSectors(partition.Start + bootSectors, sectors, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return; if(sector.Length < QNX6_SUPER_BLOCK_SIZE) return; diff --git a/Aaru.Filesystems/RBF.cs b/Aaru.Filesystems/RBF.cs index f27b2af2c..9e20b9a8d 100644 --- a/Aaru.Filesystems/RBF.cs +++ b/Aaru.Filesystems/RBF.cs @@ -34,6 +34,7 @@ using System; using System.Runtime.InteropServices; using System.Text; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Aaru.Console; using Aaru.Helpers; @@ -57,7 +58,7 @@ namespace Aaru.Filesystems /// public string Name => "OS-9 Random Block File Plugin"; /// - public Guid Id => new Guid("E864E45B-0B52-4D29-A858-7BDFA9199FB2"); + public Guid Id => new("E864E45B-0B52-4D29-A858-7BDFA9199FB2"); /// public string Author => "Natalia Portillo"; @@ -85,7 +86,10 @@ namespace Aaru.Filesystems if(partition.Start + location + sbSize >= imagePlugin.Info.Sectors) break; - byte[] sector = imagePlugin.ReadSectors(partition.Start + location, sbSize); + ErrorNumber errno = imagePlugin.ReadSectors(partition.Start + location, sbSize, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return false; if(sector.Length < Marshal.SizeOf()) return false; @@ -130,7 +134,10 @@ namespace Aaru.Filesystems if(Marshal.SizeOf() % imagePlugin.Info.SectorSize != 0) sbSize++; - byte[] sector = imagePlugin.ReadSectors(partition.Start + location, sbSize); + ErrorNumber errno = imagePlugin.ReadSectors(partition.Start + location, sbSize, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return; if(sector.Length < Marshal.SizeOf()) return; diff --git a/Aaru.Filesystems/RT11.cs b/Aaru.Filesystems/RT11.cs index cbfbcf647..437be8325 100644 --- a/Aaru.Filesystems/RT11.cs +++ b/Aaru.Filesystems/RT11.cs @@ -34,6 +34,7 @@ using System; using System.Runtime.InteropServices; using System.Text; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Aaru.Helpers; using Claunia.Encoding; @@ -55,7 +56,7 @@ namespace Aaru.Filesystems /// public string Name => "RT-11 file system"; /// - public Guid Id => new Guid("DB3E2F98-8F98-463C-8126-E937843DA024"); + public Guid Id => new("DB3E2F98-8F98-463C-8126-E937843DA024"); /// public string Author => "Natalia Portillo"; @@ -65,8 +66,11 @@ namespace Aaru.Filesystems if(1 + partition.Start >= partition.End) return false; - byte[] magicB = new byte[12]; - byte[] hbSector = imagePlugin.ReadSector(1 + partition.Start); + byte[] magicB = new byte[12]; + ErrorNumber errno = imagePlugin.ReadSector(1 + partition.Start, out byte[] hbSector); + + if(errno != ErrorNumber.NoError) + return false; if(hbSector.Length < 512) return false; @@ -86,7 +90,10 @@ namespace Aaru.Filesystems var sb = new StringBuilder(); - byte[] hbSector = imagePlugin.ReadSector(1 + partition.Start); + ErrorNumber errno = imagePlugin.ReadSector(1 + partition.Start, out byte[] hbSector); + + if(errno != ErrorNumber.NoError) + return; HomeBlock homeblock = Marshal.ByteArrayToStructureLittleEndian(hbSector); @@ -115,7 +122,7 @@ namespace Aaru.Filesystems sb.AppendFormat("Volume label: \"{0}\"", Encoding.GetString(homeblock.volname).TrimEnd()).AppendLine(); sb.AppendFormat("Checksum: 0x{0:X4} (calculated 0x{1:X4})", homeblock.checksum, check).AppendLine(); - byte[] bootBlock = imagePlugin.ReadSector(0); + imagePlugin.ReadSector(0, out byte[] bootBlock); XmlFsType = new FileSystemType { diff --git a/Aaru.Filesystems/ReFS.cs b/Aaru.Filesystems/ReFS.cs index 6e5133600..d432986e5 100644 --- a/Aaru.Filesystems/ReFS.cs +++ b/Aaru.Filesystems/ReFS.cs @@ -35,6 +35,7 @@ using System.Linq; using System.Runtime.InteropServices; using System.Text; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Aaru.Console; using Aaru.Helpers; @@ -55,7 +56,7 @@ namespace Aaru.Filesystems /// public string Name => "Resilient File System plugin"; /// - public Guid Id => new Guid("37766C4E-EBF5-4113-A712-B758B756ABD6"); + public Guid Id => new("37766C4E-EBF5-4113-A712-B758B756ABD6"); /// public FileSystemType XmlFsType { get; private set; } /// @@ -74,7 +75,10 @@ namespace Aaru.Filesystems if(partition.Start + sbSize >= partition.End) return false; - byte[] sector = imagePlugin.ReadSectors(partition.Start, sbSize); + ErrorNumber errno = imagePlugin.ReadSectors(partition.Start, sbSize, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return false; if(sector.Length < Marshal.SizeOf()) return false; @@ -100,7 +104,10 @@ namespace Aaru.Filesystems if(partition.Start + sbSize >= partition.End) return; - byte[] sector = imagePlugin.ReadSectors(partition.Start, sbSize); + ErrorNumber errno = imagePlugin.ReadSectors(partition.Start, sbSize, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return; if(sector.Length < Marshal.SizeOf()) return; diff --git a/Aaru.Filesystems/Reiser.cs b/Aaru.Filesystems/Reiser.cs index 7f1fde37e..f9fc54f99 100644 --- a/Aaru.Filesystems/Reiser.cs +++ b/Aaru.Filesystems/Reiser.cs @@ -35,6 +35,7 @@ using System.Linq; using System.Runtime.InteropServices; using System.Text; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Aaru.Helpers; using Schemas; @@ -68,7 +69,7 @@ namespace Aaru.Filesystems /// public string Name => "Reiser Filesystem Plugin"; /// - public Guid Id => new Guid("1D8CD8B8-27E6-410F-9973-D16409225FBA"); + public Guid Id => new("1D8CD8B8-27E6-410F-9973-D16409225FBA"); /// public string Author => "Natalia Portillo"; @@ -91,7 +92,10 @@ namespace Aaru.Filesystems if(partition.Start + sbAddr + sbSize >= partition.End) return false; - byte[] sector = imagePlugin.ReadSectors(partition.Start + sbAddr, sbSize); + ErrorNumber errno = imagePlugin.ReadSectors(partition.Start + sbAddr, sbSize, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return false; if(sector.Length < Marshal.SizeOf()) return false; @@ -122,7 +126,10 @@ namespace Aaru.Filesystems if(Marshal.SizeOf() % imagePlugin.Info.SectorSize != 0) sbSize++; - byte[] sector = imagePlugin.ReadSectors(partition.Start + sbAddr, sbSize); + ErrorNumber errno = imagePlugin.ReadSectors(partition.Start + sbAddr, sbSize, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return; if(sector.Length < Marshal.SizeOf()) return; @@ -219,7 +226,7 @@ namespace Aaru.Filesystems public readonly ushort reserved_for_journal; public readonly uint inode_generation; public readonly uint flags; - public Guid uuid; + public readonly Guid uuid; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public readonly byte[] label; public readonly ushort mnt_count; diff --git a/Aaru.Filesystems/Reiser4.cs b/Aaru.Filesystems/Reiser4.cs index a6abdc507..b319112f8 100644 --- a/Aaru.Filesystems/Reiser4.cs +++ b/Aaru.Filesystems/Reiser4.cs @@ -35,6 +35,7 @@ using System.Linq; using System.Runtime.InteropServices; using System.Text; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Aaru.Helpers; using Schemas; @@ -60,7 +61,7 @@ namespace Aaru.Filesystems /// public string Name => "Reiser4 Filesystem Plugin"; /// - public Guid Id => new Guid("301F2D00-E8D5-4F04-934E-81DFB21D15BA"); + public Guid Id => new("301F2D00-E8D5-4F04-934E-81DFB21D15BA"); /// public string Author => "Natalia Portillo"; @@ -83,7 +84,10 @@ namespace Aaru.Filesystems if(partition.Start + sbAddr + sbSize >= partition.End) return false; - byte[] sector = imagePlugin.ReadSectors(partition.Start + sbAddr, sbSize); + ErrorNumber errno = imagePlugin.ReadSectors(partition.Start + sbAddr, sbSize, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return false; if(sector.Length < Marshal.SizeOf()) return false; @@ -113,7 +117,10 @@ namespace Aaru.Filesystems if(Marshal.SizeOf() % imagePlugin.Info.SectorSize != 0) sbSize++; - byte[] sector = imagePlugin.ReadSectors(partition.Start + sbAddr, sbSize); + ErrorNumber errno = imagePlugin.ReadSectors(partition.Start + sbAddr, sbSize, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return; if(sector.Length < Marshal.SizeOf()) return; diff --git a/Aaru.Filesystems/SFS.cs b/Aaru.Filesystems/SFS.cs index 6be702cb5..729381b20 100644 --- a/Aaru.Filesystems/SFS.cs +++ b/Aaru.Filesystems/SFS.cs @@ -34,6 +34,7 @@ using System; using System.Runtime.InteropServices; using System.Text; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Aaru.Helpers; using Schemas; @@ -57,7 +58,7 @@ namespace Aaru.Filesystems /// public string Name => "SmartFileSystem"; /// - public Guid Id => new Guid("26550C19-3671-4A2D-BC2F-F20CEB7F48DC"); + public Guid Id => new("26550C19-3671-4A2D-BC2F-F20CEB7F48DC"); /// public string Author => "Natalia Portillo"; @@ -67,7 +68,10 @@ namespace Aaru.Filesystems if(partition.Start >= partition.End) return false; - byte[] sector = imagePlugin.ReadSector(partition.Start); + ErrorNumber errno = imagePlugin.ReadSector(partition.Start, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return false; uint magic = BigEndianBitConverter.ToUInt32(sector, 0x00); @@ -78,9 +82,14 @@ namespace Aaru.Filesystems public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information, Encoding encoding) { - Encoding = encoding ?? Encoding.GetEncoding("iso-8859-1"); - byte[] rootBlockSector = imagePlugin.ReadSector(partition.Start); - RootBlock rootBlock = Marshal.ByteArrayToStructureBigEndian(rootBlockSector); + information = ""; + Encoding = encoding ?? Encoding.GetEncoding("iso-8859-1"); + ErrorNumber errno = imagePlugin.ReadSector(partition.Start, out byte[] rootBlockSector); + + if(errno != ErrorNumber.NoError) + return; + + RootBlock rootBlock = Marshal.ByteArrayToStructureBigEndian(rootBlockSector); var sbInformation = new StringBuilder(); diff --git a/Aaru.Filesystems/SolarFS.cs b/Aaru.Filesystems/SolarFS.cs index 4a3823fac..6625568c6 100644 --- a/Aaru.Filesystems/SolarFS.cs +++ b/Aaru.Filesystems/SolarFS.cs @@ -34,6 +34,7 @@ using System; using System.Diagnostics.CodeAnalysis; using System.Text; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Aaru.Console; using Aaru.Helpers; @@ -53,7 +54,7 @@ namespace Aaru.Filesystems /// public string Name => "Solar_OS filesystem"; /// - public Guid Id => new Guid("EA3101C1-E777-4B4F-B5A3-8C57F50F6E65"); + public Guid Id => new("EA3101C1-E777-4B4F-B5A3-8C57F50F6E65"); /// public string Author => "Natalia Portillo"; @@ -63,7 +64,10 @@ namespace Aaru.Filesystems if(2 + partition.Start >= partition.End) return false; - byte[] bpb = imagePlugin.ReadSector(0 + partition.Start); + ErrorNumber errno = imagePlugin.ReadSector(0 + partition.Start, out byte[] bpb); + + if(errno != ErrorNumber.NoError) + return false; byte[] fsTypeB = new byte[8]; @@ -81,8 +85,11 @@ namespace Aaru.Filesystems Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15"); information = ""; - var sb = new StringBuilder(); - byte[] bpbSector = imagePlugin.ReadSector(0 + partition.Start); + var sb = new StringBuilder(); + ErrorNumber errno = imagePlugin.ReadSector(0 + partition.Start, out byte[] bpbSector); + + if(errno != ErrorNumber.NoError) + return; var bpb = new BiosParameterBlock { diff --git a/Aaru.Filesystems/Squash.cs b/Aaru.Filesystems/Squash.cs index ef406022f..942a9688d 100644 --- a/Aaru.Filesystems/Squash.cs +++ b/Aaru.Filesystems/Squash.cs @@ -34,6 +34,7 @@ using System; using System.Runtime.InteropServices; using System.Text; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Aaru.Helpers; using Schemas; @@ -56,7 +57,7 @@ namespace Aaru.Filesystems /// public string Name => "Squash filesystem"; /// - public Guid Id => new Guid("F8F6E46F-7A2A-48E3-9C0A-46AF4DC29E09"); + public Guid Id => new("F8F6E46F-7A2A-48E3-9C0A-46AF4DC29E09"); /// public string Author => "Natalia Portillo"; @@ -66,7 +67,10 @@ namespace Aaru.Filesystems if(partition.Start >= partition.End) return false; - byte[] sector = imagePlugin.ReadSector(partition.Start); + ErrorNumber errno = imagePlugin.ReadSector(partition.Start, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return false; uint magic = BitConverter.ToUInt32(sector, 0x00); @@ -77,9 +81,14 @@ namespace Aaru.Filesystems public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information, Encoding encoding) { - Encoding = encoding ?? Encoding.UTF8; - byte[] sector = imagePlugin.ReadSector(partition.Start); - uint magic = BitConverter.ToUInt32(sector, 0x00); + Encoding = encoding ?? Encoding.UTF8; + information = ""; + ErrorNumber errno = imagePlugin.ReadSector(partition.Start, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return; + + uint magic = BitConverter.ToUInt32(sector, 0x00); var sqSb = new SuperBlock(); bool littleEndian = true; diff --git a/Aaru.Filesystems/SysV.cs b/Aaru.Filesystems/SysV.cs index b3b4cbbaa..33a5eb4a2 100644 --- a/Aaru.Filesystems/SysV.cs +++ b/Aaru.Filesystems/SysV.cs @@ -35,6 +35,7 @@ using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Text; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Aaru.Helpers; using Schemas; @@ -78,7 +79,7 @@ namespace Aaru.Filesystems /// public string Name => "UNIX System V filesystem"; /// - public Guid Id => new Guid("9B8D016A-8561-400E-A12A-A198283C211D"); + public Guid Id => new("9B8D016A-8561-400E-A12A-A198283C211D"); /// public string Author => "Natalia Portillo"; @@ -113,13 +114,14 @@ namespace Aaru.Filesystems spc }; - foreach(byte[] sb_sector in locations. - TakeWhile(i => (ulong)i + partition.Start + sb_size_in_sectors < - imagePlugin.Info.Sectors). - Select(i => imagePlugin.ReadSectors((ulong)i + partition.Start, - sb_size_in_sectors))) + foreach(int i in locations.TakeWhile(i => (ulong)i + partition.Start + sb_size_in_sectors < + imagePlugin.Info.Sectors)) { - if(sb_sector.Length < 0x400) + ErrorNumber errno = + imagePlugin.ReadSectors((ulong)i + partition.Start, sb_size_in_sectors, out byte[] sb_sector); + + if(errno != ErrorNumber.NoError || + sb_sector.Length < 0x400) continue; uint magic = BitConverter.ToUInt32(sb_sector, 0x3F8); @@ -233,9 +235,15 @@ namespace Aaru.Filesystems spc }; + ErrorNumber errno; + foreach(int i in locations) { - sb_sector = imagePlugin.ReadSectors((ulong)i + partition.Start, sb_size_in_sectors); + errno = imagePlugin.ReadSectors((ulong)i + partition.Start, sb_size_in_sectors, out sb_sector); + + if(errno != ErrorNumber.NoError) + continue; + uint magic = BitConverter.ToUInt32(sb_sector, 0x3F8); if(magic == XENIX_MAGIC || @@ -384,7 +392,10 @@ namespace Aaru.Filesystems { byte[] xenix_strings = new byte[6]; var xnx_sb = new XenixSuperBlock(); - sb_sector = imagePlugin.ReadSectors((ulong)start + partition.Start, sb_size_in_sectors); + errno = imagePlugin.ReadSectors((ulong)start + partition.Start, sb_size_in_sectors, out sb_sector); + + if(errno != ErrorNumber.NoError) + return; if(xenix3) { @@ -552,7 +563,11 @@ namespace Aaru.Filesystems if(sysv) { - sb_sector = imagePlugin.ReadSectors((ulong)start + partition.Start, sb_size_in_sectors); + errno = imagePlugin.ReadSectors((ulong)start + partition.Start, sb_size_in_sectors, out sb_sector); + + if(errno != ErrorNumber.NoError) + return; + byte[] sysv_strings = new byte[6]; var sysv_sb = new SystemVRelease4SuperBlock @@ -721,7 +736,11 @@ namespace Aaru.Filesystems if(coherent) { - sb_sector = imagePlugin.ReadSectors((ulong)start + partition.Start, sb_size_in_sectors); + errno = imagePlugin.ReadSectors((ulong)start + partition.Start, sb_size_in_sectors, out sb_sector); + + if(errno != ErrorNumber.NoError) + return; + var coh_sb = new CoherentSuperBlock(); byte[] coh_strings = new byte[6]; @@ -794,7 +813,11 @@ namespace Aaru.Filesystems if(sys7th) { - sb_sector = imagePlugin.ReadSectors((ulong)start + partition.Start, sb_size_in_sectors); + errno = imagePlugin.ReadSectors((ulong)start + partition.Start, sb_size_in_sectors, out sb_sector); + + if(errno != ErrorNumber.NoError) + return; + var v7_sb = new UNIX7thEditionSuperBlock(); byte[] sys7_strings = new byte[6]; diff --git a/Aaru.Filesystems/UCSDPascal/File.cs b/Aaru.Filesystems/UCSDPascal/File.cs index cb2a21050..884e08d8c 100644 --- a/Aaru.Filesystems/UCSDPascal/File.cs +++ b/Aaru.Filesystems/UCSDPascal/File.cs @@ -101,8 +101,11 @@ namespace Aaru.Filesystems.UCSDPascal if(error != ErrorNumber.NoError) return error; - byte[] tmp = _device.ReadSectors((ulong)entry.FirstBlock * _multiplier, - (uint)(entry.LastBlock - entry.FirstBlock) * _multiplier); + error = _device.ReadSectors((ulong)entry.FirstBlock * _multiplier, + (uint)(entry.LastBlock - entry.FirstBlock) * _multiplier, out byte[] tmp); + + if(error != ErrorNumber.NoError) + return error; file = new byte[((entry.LastBlock - entry.FirstBlock - 1) * _device.Info.SectorSize * _multiplier) + entry.LastBytes]; diff --git a/Aaru.Filesystems/UCSDPascal/Info.cs b/Aaru.Filesystems/UCSDPascal/Info.cs index 8650772ca..aaac67e21 100644 --- a/Aaru.Filesystems/UCSDPascal/Info.cs +++ b/Aaru.Filesystems/UCSDPascal/Info.cs @@ -33,6 +33,7 @@ using System; using System.Text; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Aaru.Console; using Aaru.Helpers; @@ -54,7 +55,11 @@ namespace Aaru.Filesystems.UCSDPascal _multiplier = (uint)(imagePlugin.Info.SectorSize == 256 ? 2 : 1); // Blocks 0 and 1 are boot code - byte[] volBlock = imagePlugin.ReadSectors((_multiplier * 2) + partition.Start, _multiplier); + ErrorNumber errno = + imagePlugin.ReadSectors((_multiplier * 2) + partition.Start, _multiplier, out byte[] volBlock); + + if(errno != ErrorNumber.NoError) + return false; // On Apple II, it's little endian // TODO: Fix @@ -126,7 +131,11 @@ namespace Aaru.Filesystems.UCSDPascal return; // Blocks 0 and 1 are boot code - byte[] volBlock = imagePlugin.ReadSectors((_multiplier * 2) + partition.Start, _multiplier); + ErrorNumber errno = + imagePlugin.ReadSectors((_multiplier * 2) + partition.Start, _multiplier, out byte[] volBlock); + + if(errno != ErrorNumber.NoError) + return; // On Apple //, it's little endian // TODO: Fix @@ -191,15 +200,17 @@ namespace Aaru.Filesystems.UCSDPascal information = sbInformation.ToString(); + imagePlugin.ReadSectors(partition.Start, _multiplier * 2, out byte[] boot); + XmlFsType = new FileSystemType { - Bootable = !ArrayHelpers.ArrayIsNullOrEmpty(imagePlugin.ReadSectors(partition.Start, _multiplier * 2)), - Clusters = (ulong)volEntry.Blocks, - ClusterSize = imagePlugin.Info.SectorSize, - Files = (ulong)volEntry.Files, + Bootable = !ArrayHelpers.ArrayIsNullOrEmpty(boot), + Clusters = (ulong)volEntry.Blocks, + ClusterSize = imagePlugin.Info.SectorSize, + Files = (ulong)volEntry.Files, FilesSpecified = true, - Type = "UCSD Pascal", - VolumeName = StringHandlers.PascalToString(volEntry.VolumeName, Encoding) + Type = "UCSD Pascal", + VolumeName = StringHandlers.PascalToString(volEntry.VolumeName, Encoding) }; } } diff --git a/Aaru.Filesystems/UCSDPascal/Super.cs b/Aaru.Filesystems/UCSDPascal/Super.cs index b519106fc..74fd6b550 100644 --- a/Aaru.Filesystems/UCSDPascal/Super.cs +++ b/Aaru.Filesystems/UCSDPascal/Super.cs @@ -64,7 +64,10 @@ namespace Aaru.Filesystems.UCSDPascal _multiplier = (uint)(imagePlugin.Info.SectorSize == 256 ? 2 : 1); // Blocks 0 and 1 are boot code - _catalogBlocks = _device.ReadSectors(_multiplier * 2, _multiplier); + ErrorNumber errno = _device.ReadSectors(_multiplier * 2, _multiplier, out _catalogBlocks); + + if(errno != ErrorNumber.NoError) + return errno; // On Apple //, it's little endian // TODO: Fix @@ -93,9 +96,12 @@ namespace Aaru.Filesystems.UCSDPascal _mountedVolEntry.Files < 0) return ErrorNumber.InvalidArgument; - _catalogBlocks = _device.ReadSectors(_multiplier * 2, - (uint)(_mountedVolEntry.LastBlock - _mountedVolEntry.FirstBlock - 2) * - _multiplier); + errno = _device.ReadSectors(_multiplier * 2, + (uint)(_mountedVolEntry.LastBlock - _mountedVolEntry.FirstBlock - 2) * + _multiplier, out _catalogBlocks); + + if(errno != ErrorNumber.NoError) + return errno; int offset = 26; @@ -122,7 +128,10 @@ namespace Aaru.Filesystems.UCSDPascal offset += 26; } - _bootBlocks = _device.ReadSectors(0, 2 * _multiplier); + errno = _device.ReadSectors(0, 2 * _multiplier, out _bootBlocks); + + if(errno != ErrorNumber.NoError) + return errno; XmlFsType = new FileSystemType { diff --git a/Aaru.Filesystems/UDF.cs b/Aaru.Filesystems/UDF.cs index c72102be0..31e6a6a52 100644 --- a/Aaru.Filesystems/UDF.cs +++ b/Aaru.Filesystems/UDF.cs @@ -36,6 +36,7 @@ using System.Linq; using System.Runtime.InteropServices; using System.Text; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Aaru.Console; using Aaru.Helpers; @@ -63,7 +64,7 @@ namespace Aaru.Filesystems /// public string Name => "Universal Disk Format"; /// - public Guid Id => new Guid("83976FEC-A91B-464B-9293-56C719461BAB"); + public Guid Id => new("83976FEC-A91B-464B-9293-56C719461BAB"); /// public string Author => "Natalia Portillo"; @@ -124,7 +125,11 @@ namespace Aaru.Filesystems foreach(ulong[] position in positions.Where(position => position[0] + partition.Start + position[1] <= partition.End && position[0] < partition.End)) { - sector = imagePlugin.ReadSectors(position[0], (uint)position[1]); + ErrorNumber errno = imagePlugin.ReadSectors(position[0], (uint)position[1], out sector); + + if(errno != ErrorNumber.NoError) + continue; + anchor = Marshal.ByteArrayToStructureLittleEndian(sector); AaruConsole.DebugWriteLine("UDF Plugin", "anchor.tag.tagIdentifier = {0}", anchor.tag.tagIdentifier); @@ -177,10 +182,17 @@ namespace Aaru.Filesystems while(count < 256) { - sector = + ErrorNumber errno = imagePlugin. ReadSectors(partition.Start + (anchor.mainVolumeDescriptorSequenceExtent.location * ratio) + (count * ratio), - ratio); + ratio, out sector); + + if(errno != ErrorNumber.NoError) + { + count++; + + continue; + } var tagId = (TagIdentifier)BitConverter.ToUInt16(sector, 0); uint location = BitConverter.ToUInt32(sector, 0x0C); @@ -211,6 +223,9 @@ namespace Aaru.Filesystems public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information, Encoding encoding) { + information = ""; + ErrorNumber errno; + // UDF is always UTF-8 Encoding = Encoding.UTF8; byte[] sector; @@ -262,7 +277,11 @@ namespace Aaru.Filesystems foreach(ulong[] position in positions) { - sector = imagePlugin.ReadSectors(position[0], (uint)position[1]); + errno = imagePlugin.ReadSectors(position[0], (uint)position[1], out sector); + + if(errno != ErrorNumber.NoError) + continue; + anchor = Marshal.ByteArrayToStructureLittleEndian(sector); if(anchor.tag.tagIdentifier != TagIdentifier.AnchorVolumeDescriptorPointer || @@ -284,10 +303,13 @@ namespace Aaru.Filesystems while(count < 256) { - sector = + errno = imagePlugin. ReadSectors(partition.Start + (anchor.mainVolumeDescriptorSequenceExtent.location * ratio) + (count * ratio), - ratio); + ratio, out sector); + + if(errno != ErrorNumber.NoError) + continue; var tagId = (TagIdentifier)BitConverter.ToUInt16(sector, 0); uint location = BitConverter.ToUInt32(sector, 0x0C); @@ -315,8 +337,12 @@ namespace Aaru.Filesystems count++; } - sector = imagePlugin.ReadSectors(lvd.integritySequenceExtent.location * ratio, ratio); - lvid = Marshal.ByteArrayToStructureLittleEndian(sector); + errno = imagePlugin.ReadSectors(lvd.integritySequenceExtent.location * ratio, ratio, out sector); + + if(errno != ErrorNumber.NoError) + return; + + lvid = Marshal.ByteArrayToStructureLittleEndian(sector); if(lvid.tag.tagIdentifier == TagIdentifier.LogicalVolumeIntegrityDescriptor && lvid.tag.tagLocation == lvd.integritySequenceExtent.location) diff --git a/Aaru.Filesystems/UNICOS.cs b/Aaru.Filesystems/UNICOS.cs index 18f28192e..f5f02485e 100644 --- a/Aaru.Filesystems/UNICOS.cs +++ b/Aaru.Filesystems/UNICOS.cs @@ -35,6 +35,7 @@ using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; using System.Text; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Aaru.Console; using Aaru.Helpers; @@ -68,7 +69,7 @@ namespace Aaru.Filesystems /// public string Name => "UNICOS Filesystem Plugin"; /// - public Guid Id => new Guid("61712F04-066C-44D5-A2A0-1E44C66B33F0"); + public Guid Id => new("61712F04-066C-44D5-A2A0-1E44C66B33F0"); /// public string Author => "Natalia Portillo"; @@ -86,7 +87,10 @@ namespace Aaru.Filesystems if(partition.Start + sbSize >= partition.End) return false; - byte[] sector = imagePlugin.ReadSectors(partition.Start, sbSize); + ErrorNumber errno = imagePlugin.ReadSectors(partition.Start, sbSize, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return false; if(sector.Length < Marshal.SizeOf()) return false; @@ -114,7 +118,10 @@ namespace Aaru.Filesystems if(Marshal.SizeOf() % imagePlugin.Info.SectorSize != 0) sbSize++; - byte[] sector = imagePlugin.ReadSectors(partition.Start, sbSize); + ErrorNumber errno = imagePlugin.ReadSectors(partition.Start, sbSize, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return; if(sector.Length < Marshal.SizeOf()) return; diff --git a/Aaru.Filesystems/UNIXBFS.cs b/Aaru.Filesystems/UNIXBFS.cs index fb6fd7ee0..78bf06f13 100644 --- a/Aaru.Filesystems/UNIXBFS.cs +++ b/Aaru.Filesystems/UNIXBFS.cs @@ -34,6 +34,7 @@ using System; using System.Diagnostics.CodeAnalysis; using System.Text; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Aaru.Console; using Aaru.Helpers; @@ -55,7 +56,7 @@ namespace Aaru.Filesystems /// public string Name => "UNIX Boot filesystem"; /// - public Guid Id => new Guid("1E6E0DA6-F7E4-494C-80C6-CB5929E96155"); + public Guid Id => new("1E6E0DA6-F7E4-494C-80C6-CB5929E96155"); /// public string Author => "Natalia Portillo"; @@ -65,7 +66,12 @@ namespace Aaru.Filesystems if(2 + partition.Start >= partition.End) return false; - uint magic = BitConverter.ToUInt32(imagePlugin.ReadSector(0 + partition.Start), 0); + ErrorNumber errno = imagePlugin.ReadSector(0 + partition.Start, out byte[] tmp); + + if(errno != ErrorNumber.NoError) + return false; + + uint magic = BitConverter.ToUInt32(tmp, 0); return magic == BFS_MAGIC; } @@ -77,9 +83,13 @@ namespace Aaru.Filesystems Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15"); information = ""; - var sb = new StringBuilder(); - byte[] bfsSbSector = imagePlugin.ReadSector(0 + partition.Start); - byte[] sbStrings = new byte[6]; + var sb = new StringBuilder(); + ErrorNumber errno = imagePlugin.ReadSector(0 + partition.Start, out byte[] bfsSbSector); + + if(errno != ErrorNumber.NoError) + return; + + byte[] sbStrings = new byte[6]; var bfsSb = new SuperBlock { diff --git a/Aaru.Filesystems/VMfs.cs b/Aaru.Filesystems/VMfs.cs index a55ba48f3..f3d39a5d3 100644 --- a/Aaru.Filesystems/VMfs.cs +++ b/Aaru.Filesystems/VMfs.cs @@ -35,6 +35,7 @@ using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; using System.Text; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Aaru.Helpers; using Schemas; @@ -59,7 +60,7 @@ namespace Aaru.Filesystems /// public string Name => "VMware filesystem"; /// - public Guid Id => new Guid("EE52BDB8-B49C-4122-A3DA-AD21CBE79843"); + public Guid Id => new("EE52BDB8-B49C-4122-A3DA-AD21CBE79843"); /// public string Author => "Natalia Portillo"; @@ -74,7 +75,10 @@ namespace Aaru.Filesystems if(partition.Start + vmfsSuperOff > partition.End) return false; - byte[] sector = imagePlugin.ReadSector(partition.Start + vmfsSuperOff); + ErrorNumber errno = imagePlugin.ReadSector(partition.Start + vmfsSuperOff, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return false; uint magic = BitConverter.ToUInt32(sector, 0x00); @@ -85,9 +89,13 @@ namespace Aaru.Filesystems public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information, Encoding encoding) { - Encoding = encoding ?? Encoding.UTF8; - ulong vmfsSuperOff = VMFS_BASE / imagePlugin.Info.SectorSize; - byte[] sector = imagePlugin.ReadSector(partition.Start + vmfsSuperOff); + Encoding = encoding ?? Encoding.UTF8; + information = ""; + ulong vmfsSuperOff = VMFS_BASE / imagePlugin.Info.SectorSize; + ErrorNumber errno = imagePlugin.ReadSector(partition.Start + vmfsSuperOff, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return; VolumeInfo volInfo = Marshal.ByteArrayToStructureLittleEndian(sector); diff --git a/Aaru.Filesystems/VxFS.cs b/Aaru.Filesystems/VxFS.cs index 224d8981b..29d3f33b6 100644 --- a/Aaru.Filesystems/VxFS.cs +++ b/Aaru.Filesystems/VxFS.cs @@ -34,6 +34,7 @@ using System; using System.Runtime.InteropServices; using System.Text; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Aaru.Helpers; using Schemas; @@ -56,7 +57,7 @@ namespace Aaru.Filesystems /// public string Name => "Veritas filesystem"; /// - public Guid Id => new Guid("EC372605-7687-453C-8BEA-7E0DFF79CB03"); + public Guid Id => new("EC372605-7687-453C-8BEA-7E0DFF79CB03"); /// public string Author => "Natalia Portillo"; @@ -68,7 +69,10 @@ namespace Aaru.Filesystems if(partition.Start + vmfsSuperOff >= partition.End) return false; - byte[] sector = imagePlugin.ReadSector(partition.Start + vmfsSuperOff); + ErrorNumber errno = imagePlugin.ReadSector(partition.Start + vmfsSuperOff, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return false; uint magic = BitConverter.ToUInt32(sector, 0x00); @@ -79,9 +83,13 @@ namespace Aaru.Filesystems public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information, Encoding encoding) { - Encoding = encoding ?? Encoding.UTF8; - ulong vmfsSuperOff = VXFS_BASE / imagePlugin.Info.SectorSize; - byte[] sector = imagePlugin.ReadSector(partition.Start + vmfsSuperOff); + Encoding = encoding ?? Encoding.UTF8; + information = ""; + ulong vmfsSuperOff = VXFS_BASE / imagePlugin.Info.SectorSize; + ErrorNumber errno = imagePlugin.ReadSector(partition.Start + vmfsSuperOff, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return; SuperBlock vxSb = Marshal.ByteArrayToStructureLittleEndian(sector); diff --git a/Aaru.Filesystems/XFS.cs b/Aaru.Filesystems/XFS.cs index 53ce88108..110357055 100644 --- a/Aaru.Filesystems/XFS.cs +++ b/Aaru.Filesystems/XFS.cs @@ -56,7 +56,7 @@ namespace Aaru.Filesystems /// public string Name => "XFS Filesystem Plugin"; /// - public Guid Id => new Guid("1D8CD8B8-27E6-410F-9973-D16409225FBA"); + public Guid Id => new("1D8CD8B8-27E6-410F-9973-D16409225FBA"); /// public string Author => "Natalia Portillo"; @@ -74,7 +74,10 @@ namespace Aaru.Filesystems if((Marshal.SizeOf() + 0x400) % imagePlugin.Info.SectorSize != 0) sbSize++; - byte[] sector = imagePlugin.ReadSectors(partition.Start, sbSize); + ErrorNumber errno = imagePlugin.ReadSectors(partition.Start, sbSize, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return false; if(sector.Length < Marshal.SizeOf()) return false; @@ -110,7 +113,10 @@ namespace Aaru.Filesystems if(Marshal.SizeOf() % imagePlugin.Info.SectorSize != 0) sbSize++; - byte[] sector = imagePlugin.ReadSectors(partition.Start + location, sbSize); + ErrorNumber errno = imagePlugin.ReadSectors(partition.Start + location, sbSize, out byte[] sector); + + if(errno != ErrorNumber.NoError) + continue; if(sector.Length < Marshal.SizeOf()) return false; @@ -147,9 +153,10 @@ namespace Aaru.Filesystems if((Marshal.SizeOf() + 0x400) % imagePlugin.Info.SectorSize != 0) sbSize++; - byte[] sector = imagePlugin.ReadSectors(partition.Start, sbSize); + ErrorNumber errno = imagePlugin.ReadSectors(partition.Start, sbSize, out byte[] sector); - if(sector.Length < Marshal.SizeOf()) + if(errno != ErrorNumber.NoError || + sector.Length < Marshal.SizeOf()) return; byte[] sbpiece = new byte[Marshal.SizeOf()]; @@ -182,9 +189,10 @@ namespace Aaru.Filesystems if(Marshal.SizeOf() % imagePlugin.Info.SectorSize != 0) sbSize++; - byte[] sector = imagePlugin.ReadSectors(partition.Start + location, sbSize); + ErrorNumber errno = imagePlugin.ReadSectors(partition.Start + location, sbSize, out byte[] sector); - if(sector.Length < Marshal.SizeOf()) + if(errno != ErrorNumber.NoError || + sector.Length < Marshal.SizeOf()) return; xfsSb = Marshal.ByteArrayToStructureBigEndian(sector); diff --git a/Aaru.Filesystems/Xia.cs b/Aaru.Filesystems/Xia.cs index 27513005e..ed3e635cd 100644 --- a/Aaru.Filesystems/Xia.cs +++ b/Aaru.Filesystems/Xia.cs @@ -35,6 +35,7 @@ using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; using System.Text; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Aaru.Helpers; using Schemas; @@ -63,7 +64,7 @@ namespace Aaru.Filesystems /// public string Name => "Xia filesystem"; /// - public Guid Id => new Guid("169E1DE5-24F2-4EF6-A04D-A4B2CA66DE9D"); + public Guid Id => new("169E1DE5-24F2-4EF6-A04D-A4B2CA66DE9D"); /// public string Author => "Natalia Portillo"; @@ -79,8 +80,12 @@ namespace Aaru.Filesystems if(sbSizeInSectors + partition.Start >= partition.End) return false; - byte[] sbSector = imagePlugin.ReadSectors(partition.Start, sbSizeInSectors); - SuperBlock supblk = Marshal.ByteArrayToStructureLittleEndian(sbSector); + ErrorNumber errno = imagePlugin.ReadSectors(partition.Start, sbSizeInSectors, out byte[] sbSector); + + if(errno != ErrorNumber.NoError) + return false; + + SuperBlock supblk = Marshal.ByteArrayToStructureLittleEndian(sbSector); return supblk.s_magic == XIAFS_SUPER_MAGIC; } @@ -100,8 +105,12 @@ namespace Aaru.Filesystems if(sbSizeInBytes % imagePlugin.Info.SectorSize > 0) sbSizeInSectors++; - byte[] sbSector = imagePlugin.ReadSectors(partition.Start, sbSizeInSectors); - SuperBlock supblk = Marshal.ByteArrayToStructureLittleEndian(sbSector); + ErrorNumber errno = imagePlugin.ReadSectors(partition.Start, sbSizeInSectors, out byte[] sbSector); + + if(errno != ErrorNumber.NoError) + return; + + SuperBlock supblk = Marshal.ByteArrayToStructureLittleEndian(sbSector); sb.AppendFormat("{0} bytes per zone", supblk.s_zone_size).AppendLine(); diff --git a/Aaru.Filesystems/ZFS.cs b/Aaru.Filesystems/ZFS.cs index 65e6934b0..29522f720 100644 --- a/Aaru.Filesystems/ZFS.cs +++ b/Aaru.Filesystems/ZFS.cs @@ -36,6 +36,7 @@ using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; using System.Text; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Aaru.Helpers; using Schemas; @@ -87,7 +88,7 @@ namespace Aaru.Filesystems /// public string Name => "ZFS Filesystem Plugin"; /// - public Guid Id => new Guid("0750014F-A714-4692-A369-E23F6EC3659C"); + public Guid Id => new("0750014F-A714-4692-A369-E23F6EC3659C"); /// public string Author => "Natalia Portillo"; @@ -97,13 +98,18 @@ namespace Aaru.Filesystems if(imagePlugin.Info.SectorSize < 512) return false; - byte[] sector; - ulong magic; + byte[] sector; + ulong magic; + ErrorNumber errno; if(partition.Start + 31 < partition.End) { - sector = imagePlugin.ReadSector(partition.Start + 31); - magic = BitConverter.ToUInt64(sector, 0x1D8); + errno = imagePlugin.ReadSector(partition.Start + 31, out sector); + + if(errno != ErrorNumber.NoError) + return false; + + magic = BitConverter.ToUInt64(sector, 0x1D8); if(magic == ZEC_MAGIC || magic == ZEC_CIGAM) @@ -113,8 +119,12 @@ namespace Aaru.Filesystems if(partition.Start + 16 >= partition.End) return false; - sector = imagePlugin.ReadSector(partition.Start + 16); - magic = BitConverter.ToUInt64(sector, 0x1D8); + errno = imagePlugin.ReadSector(partition.Start + 16, out sector); + + if(errno != ErrorNumber.NoError) + return false; + + magic = BitConverter.ToUInt64(sector, 0x1D8); return magic == ZEC_MAGIC || magic == ZEC_CIGAM; } @@ -126,6 +136,7 @@ namespace Aaru.Filesystems // ZFS is always UTF-8 Encoding = Encoding.UTF8; information = ""; + ErrorNumber errno; if(imagePlugin.Info.SectorSize < 512) return; @@ -138,8 +149,12 @@ namespace Aaru.Filesystems if(partition.Start + 31 < partition.End) { - sector = imagePlugin.ReadSector(partition.Start + 31); - magic = BitConverter.ToUInt64(sector, 0x1D8); + errno = imagePlugin.ReadSector(partition.Start + 31, out sector); + + if(errno != ErrorNumber.NoError) + return; + + magic = BitConverter.ToUInt64(sector, 0x1D8); if(magic == ZEC_MAGIC || magic == ZEC_CIGAM) @@ -148,8 +163,12 @@ namespace Aaru.Filesystems if(partition.Start + 16 < partition.End) { - sector = imagePlugin.ReadSector(partition.Start + 16); - magic = BitConverter.ToUInt64(sector, 0x1D8); + errno = imagePlugin.ReadSector(partition.Start + 16, out sector); + + if(errno != ErrorNumber.NoError) + return; + + magic = BitConverter.ToUInt64(sector, 0x1D8); if(magic == ZEC_MAGIC || magic == ZEC_CIGAM) @@ -159,7 +178,10 @@ namespace Aaru.Filesystems var sb = new StringBuilder(); sb.AppendLine("ZFS filesystem"); - byte[] nvlist = imagePlugin.ReadSectors(partition.Start + nvlistOff, nvlistLen); + errno = imagePlugin.ReadSectors(partition.Start + nvlistOff, nvlistLen, out byte[] nvlist); + + if(errno != ErrorNumber.NoError) + return; sb.AppendLine(!DecodeNvList(nvlist, out Dictionary decodedNvList) ? "Could not decode nvlist" : PrintNvList(decodedNvList)); diff --git a/Aaru.Filesystems/dump.cs b/Aaru.Filesystems/dump.cs index 0dc6ec524..40379d8de 100644 --- a/Aaru.Filesystems/dump.cs +++ b/Aaru.Filesystems/dump.cs @@ -35,6 +35,7 @@ using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; using System.Text; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Aaru.Console; using Aaru.Helpers; @@ -95,7 +96,7 @@ namespace Aaru.Filesystems /// public string Name => "dump(8) Plugin"; /// - public Guid Id => new Guid("E53B4D28-C858-4800-B092-DDAE80D361B9"); + public Guid Id => new("E53B4D28-C858-4800-B092-DDAE80D361B9"); /// public FileSystemType XmlFsType { get; private set; } /// @@ -116,7 +117,10 @@ namespace Aaru.Filesystems if(Marshal.SizeOf() % imagePlugin.Info.SectorSize != 0) sbSize++; - byte[] sector = imagePlugin.ReadSectors(partition.Start, sbSize); + ErrorNumber errno = imagePlugin.ReadSectors(partition.Start, sbSize, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return false; if(sector.Length < Marshal.SizeOf()) return false; @@ -152,7 +156,10 @@ namespace Aaru.Filesystems if(Marshal.SizeOf() % imagePlugin.Info.SectorSize != 0) sbSize++; - byte[] sector = imagePlugin.ReadSectors(partition.Start, sbSize); + ErrorNumber errno = imagePlugin.ReadSectors(partition.Start, sbSize, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return; if(sector.Length < Marshal.SizeOf()) return; diff --git a/Aaru.Filesystems/exFAT.cs b/Aaru.Filesystems/exFAT.cs index ae35633a6..63fefc324 100644 --- a/Aaru.Filesystems/exFAT.cs +++ b/Aaru.Filesystems/exFAT.cs @@ -36,6 +36,7 @@ using System.Linq; using System.Runtime.InteropServices; using System.Text; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Schemas; using Marshal = Aaru.Helpers.Marshal; @@ -48,7 +49,7 @@ namespace Aaru.Filesystems [SuppressMessage("ReSharper", "UnusedMember.Local")] public sealed class exFAT : IFilesystem { - readonly Guid _oemFlashParameterGuid = new Guid("0A0C7E46-3399-4021-90C8-FA6D389C4BA2"); + readonly Guid _oemFlashParameterGuid = new("0A0C7E46-3399-4021-90C8-FA6D389C4BA2"); readonly byte[] _signature = { @@ -62,7 +63,7 @@ namespace Aaru.Filesystems /// public string Name => "Microsoft Extended File Allocation Table"; /// - public Guid Id => new Guid("8271D088-1533-4CB3-AC28-D802B68BB95C"); + public Guid Id => new("8271D088-1533-4CB3-AC28-D802B68BB95C"); /// public string Author => "Natalia Portillo"; @@ -72,7 +73,10 @@ namespace Aaru.Filesystems if(12 + partition.Start >= partition.End) return false; - byte[] vbrSector = imagePlugin.ReadSector(0 + partition.Start); + ErrorNumber errno = imagePlugin.ReadSector(0 + partition.Start, out byte[] vbrSector); + + if(errno != ErrorNumber.NoError) + return false; if(vbrSector.Length < 512) return false; @@ -92,15 +96,26 @@ namespace Aaru.Filesystems var sb = new StringBuilder(); XmlFsType = new FileSystemType(); - byte[] vbrSector = imagePlugin.ReadSector(0 + partition.Start); - VolumeBootRecord vbr = Marshal.ByteArrayToStructureLittleEndian(vbrSector); + ErrorNumber errno = imagePlugin.ReadSector(0 + partition.Start, out byte[] vbrSector); - byte[] parametersSector = imagePlugin.ReadSector(9 + partition.Start); + if(errno != ErrorNumber.NoError) + return; + + VolumeBootRecord vbr = Marshal.ByteArrayToStructureLittleEndian(vbrSector); + + errno = imagePlugin.ReadSector(9 + partition.Start, out byte[] parametersSector); + + if(errno != ErrorNumber.NoError) + return; OemParameterTable parametersTable = Marshal.ByteArrayToStructureLittleEndian(parametersSector); - byte[] chkSector = imagePlugin.ReadSector(11 + partition.Start); + errno = imagePlugin.ReadSector(11 + partition.Start, out byte[] chkSector); + + if(errno != ErrorNumber.NoError) + return; + ChecksumSector chksector = Marshal.ByteArrayToStructureLittleEndian(chkSector); sb.AppendLine("Microsoft exFAT"); diff --git a/Aaru.Filesystems/ext2FS.cs b/Aaru.Filesystems/ext2FS.cs index 972b1abab..3415909c1 100644 --- a/Aaru.Filesystems/ext2FS.cs +++ b/Aaru.Filesystems/ext2FS.cs @@ -35,6 +35,7 @@ using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; using System.Text; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Aaru.Helpers; using Schemas; @@ -171,7 +172,7 @@ namespace Aaru.Filesystems /// public string Name => "Linux extended Filesystem 2, 3 and 4"; /// - public Guid Id => new Guid("6AA91B88-150B-4A7B-AD56-F84FB2DF4184"); + public Guid Id => new("6AA91B88-150B-4A7B-AD56-F84FB2DF4184"); /// public string Author => "Natalia Portillo"; @@ -190,8 +191,13 @@ namespace Aaru.Filesystems if(sbSizeInBytes % imagePlugin.Info.SectorSize > 0) sbSizeInSectors++; - byte[] sbSector = imagePlugin.ReadSectors(sbSectorOff + partition.Start, sbSizeInSectors); - byte[] sb = new byte[sbSizeInBytes]; + ErrorNumber errno = + imagePlugin.ReadSectors(sbSectorOff + partition.Start, sbSizeInSectors, out byte[] sbSector); + + if(errno != ErrorNumber.NoError) + return false; + + byte[] sb = new byte[sbSizeInBytes]; if(sbOff + sbSizeInBytes > sbSector.Length) return false; @@ -225,8 +231,13 @@ namespace Aaru.Filesystems ulong sbSectorOff = SB_POS / imagePlugin.Info.SectorSize; uint sbOff = SB_POS % imagePlugin.Info.SectorSize; - byte[] sbSector = imagePlugin.ReadSectors(sbSectorOff + partition.Start, sbSizeInSectors); - byte[] sblock = new byte[sbSizeInBytes]; + ErrorNumber errno = + imagePlugin.ReadSectors(sbSectorOff + partition.Start, sbSizeInSectors, out byte[] sbSector); + + if(errno != ErrorNumber.NoError) + return; + + byte[] sblock = new byte[sbSizeInBytes]; Array.Copy(sbSector, sbOff, sblock, 0, sbSizeInBytes); SuperBlock supblk = Marshal.ByteArrayToStructureLittleEndian(sblock); diff --git a/Aaru.Filesystems/extFS.cs b/Aaru.Filesystems/extFS.cs index adceb53e1..d4c1f071f 100644 --- a/Aaru.Filesystems/extFS.cs +++ b/Aaru.Filesystems/extFS.cs @@ -34,6 +34,7 @@ using System; using System.Diagnostics.CodeAnalysis; using System.Text; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Schemas; @@ -54,7 +55,7 @@ namespace Aaru.Filesystems /// public string Name => "Linux extended Filesystem"; /// - public Guid Id => new Guid("076CB3A2-08C2-4D69-BC8A-FCAA2E502BE2"); + public Guid Id => new("076CB3A2-08C2-4D69-BC8A-FCAA2E502BE2"); /// public Encoding Encoding { get; private set; } /// @@ -72,8 +73,12 @@ namespace Aaru.Filesystems if(sbSectorOff + partition.Start >= partition.End) return false; - byte[] sbSector = imagePlugin.ReadSector(sbSectorOff + partition.Start); - byte[] sb = new byte[512]; + ErrorNumber errno = imagePlugin.ReadSector(sbSectorOff + partition.Start, out byte[] sbSector); + + if(errno != ErrorNumber.NoError) + return false; + + byte[] sb = new byte[512]; if(sbOff + 512 > sbSector.Length) return false; @@ -103,7 +108,11 @@ namespace Aaru.Filesystems if(sbSectorOff + partition.Start >= partition.End) return; - byte[] sblock = imagePlugin.ReadSector(sbSectorOff + partition.Start); + ErrorNumber errno = imagePlugin.ReadSector(sbSectorOff + partition.Start, out byte[] sblock); + + if(errno != ErrorNumber.NoError) + return; + byte[] sbSector = new byte[512]; Array.Copy(sblock, sbOff, sbSector, 0, 512); diff --git a/Aaru.Gui/ViewModels/Windows/ImageChecksumViewModel.cs b/Aaru.Gui/ViewModels/Windows/ImageChecksumViewModel.cs index 75ff31f6b..122ca4540 100644 --- a/Aaru.Gui/ViewModels/Windows/ImageChecksumViewModel.cs +++ b/Aaru.Gui/ViewModels/Windows/ImageChecksumViewModel.cs @@ -34,6 +34,7 @@ using System; using System.Collections.ObjectModel; using System.Reactive; using System.Threading; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Aaru.CommonTypes.Structs; using Aaru.Console; @@ -439,7 +440,8 @@ namespace Aaru.Gui.ViewModels.Windows if(Fletcher32Checked) enabledChecksums |= EnableChecksum.Fletcher32; - Checksum mediaChecksum = null; + Checksum mediaChecksum = null; + ErrorNumber errno; if(opticalMediaImage?.Tracks != null) try @@ -471,7 +473,15 @@ namespace Aaru.Gui.ViewModels.Windows Progress2Text = $"Hashing track-less sector {sector}"; }); - byte[] hiddenSector = opticalMediaImage.ReadSector(i); + errno = opticalMediaImage.ReadSector(i, out byte[] hiddenSector); + + if(errno != ErrorNumber.NoError) + { + AaruConsole.ErrorWriteLine($"Error {errno} reading sector {i}"); + _cancel = true; + + break; + } mediaChecksum?.Update(hiddenSector); } @@ -576,7 +586,16 @@ namespace Aaru.Gui.ViewModels.Windows Progress2Text = $"Hashing track-less sector {sector}"; }); - byte[] hiddenSector = opticalMediaImage.ReadSector(i); + errno = opticalMediaImage.ReadSector(i, out byte[] hiddenSector); + + if(errno != ErrorNumber.NoError) + { + AaruConsole.ErrorWriteLine($"Error {errno} reading sector {i}"); + _cancel = true; + + break; + } + mediaChecksum?.Update(hiddenSector); } @@ -627,7 +646,15 @@ namespace Aaru.Gui.ViewModels.Windows if(_inputFormat.Info.Sectors - doneSectors >= SECTORS_TO_READ) { - sector = _inputFormat.ReadSectors(doneSectors, SECTORS_TO_READ); + errno = _inputFormat.ReadSectors(doneSectors, SECTORS_TO_READ, out sector); + + if(errno != ErrorNumber.NoError) + { + AaruConsole.ErrorWriteLine($"Error {errno} reading sector {doneSectors}"); + _cancel = true; + + continue; + } ulong doneSectorsToInvoke = doneSectors; @@ -643,7 +670,17 @@ namespace Aaru.Gui.ViewModels.Windows } else { - sector = _inputFormat.ReadSectors(doneSectors, (uint)(_inputFormat.Info.Sectors - doneSectors)); + errno = _inputFormat.ReadSectors(doneSectors, (uint)(_inputFormat.Info.Sectors - doneSectors), + out sector); + + if(errno != ErrorNumber.NoError) + { + AaruConsole.ErrorWriteLine($"Error {errno} reading sector {doneSectors}"); + _cancel = true; + + continue; + } + ulong doneSectorsToInvoke = doneSectors; await Dispatcher.UIThread.InvokeAsync(() => diff --git a/Aaru.Gui/ViewModels/Windows/ImageConvertViewModel.cs b/Aaru.Gui/ViewModels/Windows/ImageConvertViewModel.cs index e5fb30955..dab5eb744 100644 --- a/Aaru.Gui/ViewModels/Windows/ImageConvertViewModel.cs +++ b/Aaru.Gui/ViewModels/Windows/ImageConvertViewModel.cs @@ -842,6 +842,8 @@ namespace Aaru.Gui.ViewModels.Windows } } + ErrorNumber errno; + foreach(MediaTagType mediaTag in _inputFormat.Info.ReadableMediaTags.TakeWhile(mediaTag => !_cancel)) { await Dispatcher.UIThread.InvokeAsync(() => @@ -855,9 +857,10 @@ namespace Aaru.Gui.ViewModels.Windows if(ForceChecked && !outputFormat.SupportedMediaTags.Contains(mediaTag)) continue; - var errno = _inputFormat.ReadMediaTag(mediaTag, out byte[] tag); + errno = _inputFormat.ReadMediaTag(mediaTag, out byte[] tag); - if(errno == ErrorNumber.NoError && outputFormat.WriteMediaTag(tag, mediaTag)) + if(errno == ErrorNumber.NoError && + outputFormat.WriteMediaTag(tag, mediaTag)) continue; if(ForceChecked) @@ -865,7 +868,8 @@ namespace Aaru.Gui.ViewModels.Windows warning = true; if(errno == ErrorNumber.NoError) - AaruConsole.ErrorWriteLine("Error {0} writing media tag, continuing...", outputFormat.ErrorMessage); + AaruConsole.ErrorWriteLine("Error {0} writing media tag, continuing...", + outputFormat.ErrorMessage); else AaruConsole.ErrorWriteLine("Error {0} reading media tag, continuing...", errno); } @@ -881,7 +885,8 @@ namespace Aaru.Gui.ViewModels.Windows AaruConsole.ErrorWriteLine("Error {0} writing media tag, not continuing...", outputFormat.ErrorMessage); - }else + } + else { await Dispatcher.UIThread.InvokeAsync(action: async () => await MessageBoxManager. @@ -889,8 +894,7 @@ namespace Aaru.Gui.ViewModels.Windows $"Error {errno} reading media tag, not continuing...", icon: Icon.Error).ShowDialog(_view)); - AaruConsole.ErrorWriteLine("Error {0} reading media tag, not continuing...", - errno); + AaruConsole.ErrorWriteLine("Error {0} reading media tag, not continuing...", errno); } return; @@ -969,15 +973,36 @@ namespace Aaru.Gui.ViewModels.Windows } else { - if(sectorsToDo == 1) - { - sector = _inputFormat.ReadSector(doneSectors); - result = outputFormat.WriteSector(sector, doneSectors); - } + errno = sectorsToDo == 1 ? _inputFormat.ReadSector(doneSectors, out sector) + : _inputFormat.ReadSectors(doneSectors, sectorsToDo, out sector); + + if(errno == ErrorNumber.NoError) + result = sectorsToDo == 1 ? outputFormat.WriteSector(sector, doneSectors) + : outputFormat.WriteSectors(sector, doneSectors, sectorsToDo); else { - sector = _inputFormat.ReadSectors(doneSectors, sectorsToDo); - result = outputFormat.WriteSectors(sector, doneSectors, sectorsToDo); + result = true; + + if(ForceChecked) + { + warning = true; + + AaruConsole.ErrorWriteLine("Error {0} reading sector {1}, continuing...", errno, + doneSectors); + } + else + { + await Dispatcher.UIThread.InvokeAsync(action: async () => await MessageBoxManager. + GetMessageBoxStandardWindow("Error", + $"Error {errno} reading sector {doneSectors}, not continuing...", + icon: Icon.Error). + ShowDialog(_view)); + + AaruConsole.ErrorWriteLine("Error {0} reading sector {1}, not continuing...", errno, + doneSectors); + + return; + } } } @@ -1261,17 +1286,37 @@ namespace Aaru.Gui.ViewModels.Windows } else { - if(sectorsToDo == 1) - { - sector = _inputFormat.ReadSector(doneSectors + track.StartSector); - result = outputFormat.WriteSector(sector, doneSectors + track.StartSector); - } + errno = sectorsToDo == 1 + ? _inputFormat.ReadSector(doneSectors + track.StartSector, out sector) + : _inputFormat.ReadSectors(doneSectors + track.StartSector, sectorsToDo, + out sector); + + if(errno == ErrorNumber.NoError) + result = sectorsToDo == 1 + ? outputFormat.WriteSector(sector, doneSectors + track.StartSector) + : outputFormat.WriteSectors(sector, doneSectors + track.StartSector, + sectorsToDo); else { - sector = _inputFormat.ReadSectors(doneSectors + track.StartSector, sectorsToDo); + result = true; - result = outputFormat.WriteSectors(sector, doneSectors + track.StartSector, - sectorsToDo); + if(ForceChecked) + { + warning = true; + + AaruConsole.ErrorWriteLine("Error {0} reading sector {1}, continuing...", errno, + doneSectors); + } + else + { + await Dispatcher.UIThread.InvokeAsync(action: async () => await MessageBoxManager. + GetMessageBoxStandardWindow("Error", + $"Error {errno} reading sector {doneSectors}, not continuing...", + icon: Icon.Error). + ShowDialog(_view)); + + return; + } } } diff --git a/Aaru.Gui/ViewModels/Windows/ViewSectorViewModel.cs b/Aaru.Gui/ViewModels/Windows/ViewSectorViewModel.cs index 6c3960d54..6c348aac6 100644 --- a/Aaru.Gui/ViewModels/Windows/ViewSectorViewModel.cs +++ b/Aaru.Gui/ViewModels/Windows/ViewSectorViewModel.cs @@ -30,6 +30,7 @@ // Copyright © 2011-2021 Natalia Portillo // ****************************************************************************/ +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Aaru.Helpers; using JetBrains.Annotations; @@ -79,10 +80,16 @@ namespace Aaru.Gui.ViewModels.Windows { this.RaiseAndSetIfChanged(ref _sectorNumber, value); - PrintHexText = - PrintHex. - ByteArrayToHexArrayString(LongSectorChecked ? _inputFormat.ReadSectorLong((ulong)SectorNumber) : _inputFormat.ReadSector((ulong)SectorNumber), - HEX_COLUMNS); + byte[] sector; + ErrorNumber errno = ErrorNumber.NoError; + + if(LongSectorChecked) + sector = _inputFormat.ReadSectorLong((ulong)SectorNumber); + else + errno = _inputFormat.ReadSector((ulong)SectorNumber, out sector); + + if(errno == ErrorNumber.NoError) + PrintHexText = PrintHex.ByteArrayToHexArrayString(sector, HEX_COLUMNS); } } diff --git a/Aaru.Images/AaruFormat/Read.cs b/Aaru.Images/AaruFormat/Read.cs index ce3636a1e..ce9fb9d3f 100644 --- a/Aaru.Images/AaruFormat/Read.cs +++ b/Aaru.Images/AaruFormat/Read.cs @@ -1377,7 +1377,11 @@ namespace Aaru.DiscImages foreach(Track trk in tracks) { - byte[] sector = ReadSector(trk.StartSector); + ErrorNumber errno = ReadSector(trk.StartSector, out byte[] sector); + + if(errno != ErrorNumber.NoError) + continue; + trk.BytesPerSector = sector.Length; trk.RawBytesPerSector = @@ -1493,11 +1497,12 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSector(ulong sectorAddress) + public ErrorNumber ReadSector(ulong sectorAddress, out byte[] buffer) { + buffer = null; + if(sectorAddress > _imageInfo.Sectors - 1) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), - $"Sector address {sectorAddress} not found"); + return ErrorNumber.OutOfRange; ulong ddtEntry = GetDdtEntry(sectorAddress); uint offsetMask = (uint)((1 << _shift) - 1); @@ -1506,18 +1511,20 @@ namespace Aaru.DiscImages // Partially written image... as we can't know the real sector size just assume it's common :/ if(ddtEntry == 0) - return new byte[_imageInfo.SectorSize]; + { + buffer = new byte[_imageInfo.SectorSize]; - byte[] sector; + return ErrorNumber.NoError; + } // Check if block is cached if(_blockCache.TryGetValue(blockOffset, out byte[] block) && _blockHeaderCache.TryGetValue(blockOffset, out BlockHeader blockHeader)) { - sector = new byte[blockHeader.sectorSize]; - Array.Copy(block, (long)(offset * blockHeader.sectorSize), sector, 0, blockHeader.sectorSize); + buffer = new byte[blockHeader.sectorSize]; + Array.Copy(block, (long)(offset * blockHeader.sectorSize), buffer, 0, blockHeader.sectorSize); - return sector; + return ErrorNumber.NoError; } // Read block header @@ -1571,9 +1578,7 @@ namespace Aaru.DiscImages GC.GetTotalMemory(false)); break; - default: - throw new - ImageNotSupportedException($"Found unsupported compression algorithm {(ushort)blockHeader.compression}"); + default: return ErrorNumber.NotSupported; } // Check if cache needs to be emptied @@ -1589,12 +1594,12 @@ namespace Aaru.DiscImages _blockHeaderCache.Add(blockOffset, blockHeader); _blockCache.Add(blockOffset, block); - sector = new byte[blockHeader.sectorSize]; - Array.Copy(block, (long)(offset * blockHeader.sectorSize), sector, 0, blockHeader.sectorSize); + buffer = new byte[blockHeader.sectorSize]; + Array.Copy(block, (long)(offset * blockHeader.sectorSize), buffer, 0, blockHeader.sectorSize); AaruConsole.DebugWriteLine("Aaru Format plugin", "Memory snapshot: {0} bytes", GC.GetTotalMemory(false)); - return sector; + return ErrorNumber.NoError; } /// @@ -1611,7 +1616,9 @@ namespace Aaru.DiscImages if(trk?.Sequence != track) throw new ArgumentOutOfRangeException(nameof(track), "Track does not exist in disc image"); - return ReadSector(trk.StartSector + sectorAddress); + ReadSector(trk.StartSector + sectorAddress, out byte[] sector); + + return sector; } /// @@ -1629,24 +1636,31 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSectors(ulong sectorAddress, uint length) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, out byte[] buffer) { + buffer = null; + if(sectorAddress > _imageInfo.Sectors - 1) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), - $"Sector address {sectorAddress} not found"); + return ErrorNumber.OutOfRange; if(sectorAddress + length > _imageInfo.Sectors) - throw new ArgumentOutOfRangeException(nameof(length), "Requested more sectors than available"); + return ErrorNumber.OutOfRange; var ms = new MemoryStream(); for(uint i = 0; i < length; i++) { - byte[] sector = ReadSector(sectorAddress + i); + ErrorNumber errno = ReadSector(sectorAddress + i, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return errno; + ms.Write(sector, 0, sector.Length); } - return ms.ToArray(); + buffer = ms.ToArray(); + + return ErrorNumber.NoError; } /// @@ -1942,7 +1956,9 @@ namespace Aaru.DiscImages throw new ArgumentOutOfRangeException(nameof(length), $"Requested more sectors ({length + sectorAddress}) than present in track ({trk.EndSector - trk.StartSector + 1}), won't cross tracks"); - return ReadSectors(trk.StartSector + sectorAddress, length); + ReadSectors(trk.StartSector + sectorAddress, length, out byte[] buffer); + + return buffer; } /// @@ -1966,6 +1982,8 @@ namespace Aaru.DiscImages /// public byte[] ReadSectorLong(ulong sectorAddress) { + ErrorNumber errno; + switch(_imageInfo.XmlMediaType) { case XmlMediaType.OpticalDisc: @@ -1984,10 +2002,14 @@ namespace Aaru.DiscImages if((_sectorSuffix == null || _sectorPrefix == null) && (_sectorSuffixMs == null || _sectorPrefixMs == null)) - return ReadSector(sectorAddress); + { + errno = ReadSector(sectorAddress, out byte[] buffer); + + return errno != ErrorNumber.NoError ? null : buffer; + } byte[] sector = new byte[2352]; - byte[] data = ReadSector(sectorAddress); + errno = ReadSector(sectorAddress, out byte[] data); switch(trk.Type) { @@ -2182,8 +2204,9 @@ namespace Aaru.DiscImages /// public byte[] ReadSectorsLong(ulong sectorAddress, uint length) { - byte[] sectors; - byte[] data; + byte[] sectors; + byte[] data; + ErrorNumber errno; switch(_imageInfo.XmlMediaType) { @@ -2209,7 +2232,10 @@ namespace Aaru.DiscImages { // These types only contain user data case TrackType.Audio: - case TrackType.Data: return ReadSectors(sectorAddress, length); + case TrackType.Data: + errno = ReadSectors(sectorAddress, length, out data); + + return errno == ErrorNumber.NoError ? data : null; // Join prefix (sync, header) with user data with suffix (edc, ecc p, ecc q) case TrackType.CdMode1: @@ -2217,7 +2243,10 @@ namespace Aaru.DiscImages _sectorSuffix != null) { sectors = new byte[2352 * length]; - data = ReadSectors(sectorAddress, length); + errno = ReadSectors(sectorAddress, length, out data); + + if(errno != ErrorNumber.NoError) + return null; for(uint i = 0; i < length; i++) { @@ -2246,7 +2275,11 @@ namespace Aaru.DiscImages return sectors; } else - return ReadSectors(sectorAddress, length); + { + errno = ReadSectors(sectorAddress, length, out data); + + return errno == ErrorNumber.NoError ? data : null; + } // Join prefix (sync, header) with user data case TrackType.CdMode2Formless: @@ -2256,7 +2289,10 @@ namespace Aaru.DiscImages _sectorSuffix != null) { sectors = new byte[2352 * length]; - data = ReadSectors(sectorAddress, length); + errno = ReadSectors(sectorAddress, length, out data); + + if(errno != ErrorNumber.NoError) + return null; for(uint i = 0; i < length; i++) { @@ -2282,7 +2318,9 @@ namespace Aaru.DiscImages return sectors; } - return ReadSectors(sectorAddress, length); + errno = ReadSectors(sectorAddress, length, out data); + + return errno == ErrorNumber.NoError ? data : null; } break; @@ -2297,7 +2335,11 @@ namespace Aaru.DiscImages case MediaType.AppleWidget: case MediaType.PriamDataTower: if(_sectorSubchannel == null) - return ReadSector(sectorAddress); + { + errno = ReadSector(sectorAddress, out data); + + return errno == ErrorNumber.NoError ? data : null; + } uint tagSize = 0; @@ -2321,7 +2363,11 @@ namespace Aaru.DiscImages } uint sectorSize = 512 + tagSize; - data = ReadSectors(sectorAddress, length); + errno = ReadSectors(sectorAddress, length, out data); + + if(errno != ErrorNumber.NoError) + return null; + sectors = new byte[(sectorSize + 512) * length]; for(uint i = 0; i < length; i++) diff --git a/Aaru.Images/AaruFormat/Write.cs b/Aaru.Images/AaruFormat/Write.cs index 40d4e3a3c..e4a9380f6 100644 --- a/Aaru.Images/AaruFormat/Write.cs +++ b/Aaru.Images/AaruFormat/Write.cs @@ -1496,7 +1496,11 @@ namespace Aaru.DiscImages foreach(Track trk in tracks) { - byte[] sector = ReadSector(trk.StartSector); + ErrorNumber errno = ReadSector(trk.StartSector, out byte[] sector); + + if(errno != ErrorNumber.NoError) + continue; + trk.BytesPerSector = sector.Length; trk.RawBytesPerSector = diff --git a/Aaru.Images/Alcohol120/Read.cs b/Aaru.Images/Alcohol120/Read.cs index 08085d786..8aa8482f2 100644 --- a/Aaru.Images/Alcohol120/Read.cs +++ b/Aaru.Images/Alcohol120/Read.cs @@ -781,7 +781,8 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSector(ulong sectorAddress) => ReadSectors(sectorAddress, 1); + public ErrorNumber ReadSector(ulong sectorAddress, out byte[] buffer) => + ReadSectors(sectorAddress, 1, out buffer); /// public byte[] ReadSectorTag(ulong sectorAddress, SectorTagType tag) => ReadSectorsTag(sectorAddress, 1, tag); @@ -794,8 +795,10 @@ namespace Aaru.DiscImages ReadSectorsTag(sectorAddress, 1, track, tag); /// - public byte[] ReadSectors(ulong sectorAddress, uint length) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, out byte[] buffer) { + buffer = null; + foreach(KeyValuePair kvp in _offsetMap) if(sectorAddress >= kvp.Value) foreach(Track track in _alcTracks.Values) @@ -804,11 +807,15 @@ namespace Aaru.DiscImages !_alcTrackExtras.TryGetValue(track.point, out TrackExtra extra)) continue; - if(sectorAddress - kvp.Value < extra.sectors + extra.pregap) - return ReadSectors(sectorAddress - kvp.Value, length, kvp.Key); + if(sectorAddress - kvp.Value >= extra.sectors + extra.pregap) + continue; + + buffer = ReadSectors(sectorAddress - kvp.Value, length, kvp.Key); + + return ErrorNumber.NoError; } - throw new ArgumentOutOfRangeException(nameof(sectorAddress), "Sector address not found"); + return ErrorNumber.SectorNotFound; } /// diff --git a/Aaru.Images/Anex86/Read.cs b/Aaru.Images/Anex86/Read.cs index 3d56ca52b..350935fa6 100644 --- a/Aaru.Images/Anex86/Read.cs +++ b/Aaru.Images/Anex86/Read.cs @@ -30,7 +30,6 @@ // Copyright © 2011-2021 Natalia Portillo // ****************************************************************************/ -using System; using System.IO; using Aaru.CommonTypes; using Aaru.CommonTypes.Enums; @@ -82,18 +81,21 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSector(ulong sectorAddress) => ReadSectors(sectorAddress, 1); + public ErrorNumber ReadSector(ulong sectorAddress, out byte[] buffer) => + ReadSectors(sectorAddress, 1, out buffer); /// - public byte[] ReadSectors(ulong sectorAddress, uint length) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, out byte[] buffer) { + buffer = null; + if(sectorAddress > _imageInfo.Sectors - 1) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), "Sector address not found"); + return ErrorNumber.OutOfRange; if(sectorAddress + length > _imageInfo.Sectors) - throw new ArgumentOutOfRangeException(nameof(length), "Requested more sectors than available"); + return ErrorNumber.OutOfRange; - byte[] buffer = new byte[length * _imageInfo.SectorSize]; + buffer = new byte[length * _imageInfo.SectorSize]; Stream stream = _anexImageFilter.GetDataForkStream(); @@ -101,7 +103,7 @@ namespace Aaru.DiscImages stream.Read(buffer, 0, (int)(length * _imageInfo.SectorSize)); - return buffer; + return ErrorNumber.NoError; } } } \ No newline at end of file diff --git a/Aaru.Images/Apple2MG/Read.cs b/Aaru.Images/Apple2MG/Read.cs index 981e0e506..a0a8c6d8e 100644 --- a/Aaru.Images/Apple2MG/Read.cs +++ b/Aaru.Images/Apple2MG/Read.cs @@ -115,7 +115,11 @@ namespace Aaru.DiscImages var noFilter = new ZZZNoFilter(); noFilter.Open(tmp); nibPlugin.Open(noFilter); - _decodedImage = nibPlugin.ReadSectors(0, (uint)nibPlugin.Info.Sectors); + ErrorNumber errno = nibPlugin.ReadSectors(0, (uint)nibPlugin.Info.Sectors, out _decodedImage); + + if(errno != ErrorNumber.NoError) + return errno; + _imageInfo.Sectors = nibPlugin.Info.Sectors; _imageInfo.SectorSize = nibPlugin.Info.SectorSize; @@ -302,18 +306,21 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSector(ulong sectorAddress) => ReadSectors(sectorAddress, 1); + public ErrorNumber ReadSector(ulong sectorAddress, out byte[] buffer) => + ReadSectors(sectorAddress, 1, out buffer); /// - public byte[] ReadSectors(ulong sectorAddress, uint length) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, out byte[] buffer) { + buffer = null; + if(sectorAddress > _imageInfo.Sectors - 1) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), "Sector address not found"); + return ErrorNumber.OutOfRange; if(sectorAddress + length > _imageInfo.Sectors) - throw new ArgumentOutOfRangeException(nameof(length), "Requested more sectors than available"); + return ErrorNumber.OutOfRange; - byte[] buffer = new byte[length * _imageInfo.SectorSize]; + buffer = new byte[length * _imageInfo.SectorSize]; if(_decodedImage != null) Array.Copy(_decodedImage, (long)(sectorAddress * _imageInfo.SectorSize), buffer, 0, @@ -328,7 +335,7 @@ namespace Aaru.DiscImages stream.Read(buffer, 0, (int)(length * _imageInfo.SectorSize)); } - return buffer; + return ErrorNumber.NoError; } } } \ No newline at end of file diff --git a/Aaru.Images/AppleDOS/Read.cs b/Aaru.Images/AppleDOS/Read.cs index 8f1e12faf..0d9cdb7e5 100644 --- a/Aaru.Images/AppleDOS/Read.cs +++ b/Aaru.Images/AppleDOS/Read.cs @@ -96,22 +96,25 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSector(ulong sectorAddress) => ReadSectors(sectorAddress, 1); + public ErrorNumber ReadSector(ulong sectorAddress, out byte[] buffer) => + ReadSectors(sectorAddress, 1, out buffer); /// - public byte[] ReadSectors(ulong sectorAddress, uint length) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, out byte[] buffer) { + buffer = null; + if(sectorAddress > _imageInfo.Sectors - 1) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), "Sector address not found"); + return ErrorNumber.OutOfRange; if(sectorAddress + length > _imageInfo.Sectors) - throw new ArgumentOutOfRangeException(nameof(length), "Requested more sectors than available"); + return ErrorNumber.OutOfRange; - byte[] buffer = new byte[length * _imageInfo.SectorSize]; + buffer = new byte[length * _imageInfo.SectorSize]; Array.Copy(_deinterleaved, (int)(sectorAddress * _imageInfo.SectorSize), buffer, 0, buffer.Length); - return buffer; + return ErrorNumber.NoError; } } } \ No newline at end of file diff --git a/Aaru.Images/AppleNIB/Read.cs b/Aaru.Images/AppleNIB/Read.cs index 7e61ee545..fdd08117e 100644 --- a/Aaru.Images/AppleNIB/Read.cs +++ b/Aaru.Images/AppleNIB/Read.cs @@ -167,36 +167,43 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSector(ulong sectorAddress) + public ErrorNumber ReadSector(ulong sectorAddress, out byte[] buffer) { + buffer = null; + if(sectorAddress > _imageInfo.Sectors - 1) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), - $"Sector address {sectorAddress} not found"); + return ErrorNumber.OutOfRange; - _cookedSectors.TryGetValue(sectorAddress, out byte[] temp); - - return temp; + return _cookedSectors.TryGetValue(sectorAddress, out buffer) ? ErrorNumber.NoError + : ErrorNumber.SectorNotFound; } /// - public byte[] ReadSectors(ulong sectorAddress, uint length) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, out byte[] buffer) { + buffer = null; + if(sectorAddress > _imageInfo.Sectors - 1) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), - $"Sector address {sectorAddress} not found"); + return ErrorNumber.OutOfRange; if(sectorAddress + length > _imageInfo.Sectors) - throw new ArgumentOutOfRangeException(nameof(length), "Requested more sectors than available"); + return ErrorNumber.OutOfRange; var ms = new MemoryStream(); for(uint i = 0; i < length; i++) { - byte[] sector = ReadSector(sectorAddress + i); + ErrorNumber errno = ReadSector(sectorAddress + i, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return errno; + ms.Write(sector, 0, sector.Length); } - return ms.ToArray(); + buffer = ms.ToArray(); + + return ErrorNumber.NoError; } /// diff --git a/Aaru.Images/Apridisk/Read.cs b/Aaru.Images/Apridisk/Read.cs index e6f190321..a9143a970 100644 --- a/Aaru.Images/Apridisk/Read.cs +++ b/Aaru.Images/Apridisk/Read.cs @@ -30,7 +30,6 @@ // Copyright © 2011-2021 Natalia Portillo // ****************************************************************************/ -using System; using System.IO; using Aaru.CommonTypes; using Aaru.CommonTypes.Enums; @@ -231,40 +230,51 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSector(ulong sectorAddress) + public ErrorNumber ReadSector(ulong sectorAddress, out byte[] buffer) { + buffer = null; (ushort cylinder, byte head, byte sector) = LbaToChs(sectorAddress); if(cylinder >= _sectorsData.Length) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), "Sector address not found"); + return ErrorNumber.SectorNotFound; if(head >= _sectorsData[cylinder].Length) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), "Sector address not found"); + return ErrorNumber.SectorNotFound; if(sector > _sectorsData[cylinder][head].Length) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), "Sector address not found"); + return ErrorNumber.SectorNotFound; - return _sectorsData[cylinder][head][sector]; + buffer = _sectorsData[cylinder][head][sector]; + + return ErrorNumber.NoError; } /// - public byte[] ReadSectors(ulong sectorAddress, uint length) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, out byte[] buffer) { + buffer = null; + if(sectorAddress > _imageInfo.Sectors - 1) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), "Sector address not found"); + return ErrorNumber.OutOfRange; if(sectorAddress + length > _imageInfo.Sectors) - throw new ArgumentOutOfRangeException(nameof(length), "Requested more sectors than available"); + return ErrorNumber.OutOfRange; - var buffer = new MemoryStream(); + var ms = new MemoryStream(); for(uint i = 0; i < length; i++) { - byte[] sector = ReadSector(sectorAddress + i); - buffer.Write(sector, 0, sector.Length); + ErrorNumber errno = ReadSector(sectorAddress + i, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return errno; + + ms.Write(sector, 0, sector.Length); } - return buffer.ToArray(); + buffer = ms.ToArray(); + + return ErrorNumber.NoError; } } } \ No newline at end of file diff --git a/Aaru.Images/BLU/Read.cs b/Aaru.Images/BLU/Read.cs index 41cb63606..ecbae6019 100644 --- a/Aaru.Images/BLU/Read.cs +++ b/Aaru.Images/BLU/Read.cs @@ -153,24 +153,27 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSector(ulong sectorAddress) => ReadSectors(sectorAddress, 1); + public ErrorNumber ReadSector(ulong sectorAddress, out byte[] buffer) => + ReadSectors(sectorAddress, 1, out buffer); /// public byte[] ReadSectorTag(ulong sectorAddress, SectorTagType tag) => ReadSectorsTag(sectorAddress, 1, tag); /// - public byte[] ReadSectors(ulong sectorAddress, uint length) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, out byte[] buffer) { + buffer = null; + if(sectorAddress > _imageInfo.Sectors - 1) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), "Sector address not found"); + return ErrorNumber.OutOfRange; if(sectorAddress + length > _imageInfo.Sectors) - throw new ArgumentOutOfRangeException(nameof(length), "Requested more sectors than available"); + return ErrorNumber.OutOfRange; - var buffer = new MemoryStream(); - int seek = 0; - int read = 0x200; - int skip = _bptag; + var ms = new MemoryStream(); + int seek = 0; + int read = 0x200; + int skip = _bptag; Stream stream = _bluImageFilter.GetDataForkStream(); stream.Seek((long)((sectorAddress + 1) * _imageHeader.BytesPerBlock), SeekOrigin.Begin); @@ -180,11 +183,13 @@ namespace Aaru.DiscImages stream.Seek(seek, SeekOrigin.Current); byte[] sector = new byte[read]; stream.Read(sector, 0, read); - buffer.Write(sector, 0, read); + ms.Write(sector, 0, read); stream.Seek(skip, SeekOrigin.Current); } - return buffer.ToArray(); + buffer = ms.ToArray(); + + return ErrorNumber.NoError; } /// diff --git a/Aaru.Images/BlindWrite4/Read.cs b/Aaru.Images/BlindWrite4/Read.cs index 6502045c2..1c183ec99 100644 --- a/Aaru.Images/BlindWrite4/Read.cs +++ b/Aaru.Images/BlindWrite4/Read.cs @@ -832,7 +832,8 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSector(ulong sectorAddress) => ReadSectors(sectorAddress, 1); + public ErrorNumber ReadSector(ulong sectorAddress, out byte[] buffer) => + ReadSectors(sectorAddress, 1, out buffer); /// public byte[] ReadSectorTag(ulong sectorAddress, SectorTagType tag) => ReadSectorsTag(sectorAddress, 1, tag); @@ -845,15 +846,21 @@ namespace Aaru.DiscImages ReadSectorsTag(sectorAddress, 1, track, tag); /// - public byte[] ReadSectors(ulong sectorAddress, uint length) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, out byte[] buffer) { + buffer = null; + foreach(KeyValuePair kvp in from kvp in _offsetMap where sectorAddress >= kvp.Value from track in Tracks where track.Sequence == kvp.Key where sectorAddress - kvp.Value < track.EndSector - track.StartSector + 1 select kvp) - return ReadSectors(sectorAddress - kvp.Value, length, kvp.Key); + { + buffer = ReadSectors(sectorAddress - kvp.Value, length, kvp.Key); - throw new ArgumentOutOfRangeException(nameof(sectorAddress), "Sector address not found"); + return ErrorNumber.NoError; + } + + return ErrorNumber.SectorNotFound; } /// diff --git a/Aaru.Images/BlindWrite5/Read.cs b/Aaru.Images/BlindWrite5/Read.cs index 680d550ed..325303e4b 100644 --- a/Aaru.Images/BlindWrite5/Read.cs +++ b/Aaru.Images/BlindWrite5/Read.cs @@ -1433,7 +1433,8 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSector(ulong sectorAddress) => ReadSectors(sectorAddress, 1); + public ErrorNumber ReadSector(ulong sectorAddress, out byte[] buffer) => + ReadSectors(sectorAddress, 1, out buffer); /// public byte[] ReadSectorTag(ulong sectorAddress, SectorTagType tag) => ReadSectorsTag(sectorAddress, 1, tag); @@ -1446,15 +1447,21 @@ namespace Aaru.DiscImages ReadSectorsTag(sectorAddress, 1, track, tag); /// - public byte[] ReadSectors(ulong sectorAddress, uint length) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, out byte[] buffer) { + buffer = null; + foreach(KeyValuePair kvp in from kvp in _offsetMap where sectorAddress >= kvp.Value from track in Tracks where track.Sequence == kvp.Key where sectorAddress - kvp.Value < track.EndSector - track.StartSector + 1 select kvp) - return ReadSectors(sectorAddress - kvp.Value, length, kvp.Key); + { + buffer = ReadSectors(sectorAddress - kvp.Value, length, kvp.Key); - throw new ArgumentOutOfRangeException(nameof(sectorAddress), "Sector address not found"); + return ErrorNumber.NoError; + } + + return ErrorNumber.SectorNotFound; } /// diff --git a/Aaru.Images/CDRDAO/Read.cs b/Aaru.Images/CDRDAO/Read.cs index f83fcb542..0aab46435 100644 --- a/Aaru.Images/CDRDAO/Read.cs +++ b/Aaru.Images/CDRDAO/Read.cs @@ -913,7 +913,7 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSector(ulong sectorAddress) => ReadSectors(sectorAddress, 1); + public ErrorNumber ReadSector(ulong sectorAddress, out byte[] buffer) => ReadSectors(sectorAddress, 1, out buffer); /// public byte[] ReadSectorTag(ulong sectorAddress, SectorTagType tag) => ReadSectorsTag(sectorAddress, 1, tag); @@ -926,15 +926,20 @@ namespace Aaru.DiscImages ReadSectorsTag(sectorAddress, 1, track, tag); /// - public byte[] ReadSectors(ulong sectorAddress, uint length) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, out byte[] buffer) { + buffer = null; foreach(KeyValuePair kvp in from kvp in _offsetmap where sectorAddress >= kvp.Value from cdrdaoTrack in _discimage.Tracks where cdrdaoTrack.Sequence == kvp.Key where sectorAddress - kvp.Value < cdrdaoTrack.Sectors select kvp) - return ReadSectors(sectorAddress - kvp.Value, length, kvp.Key); + { + buffer= ReadSectors(sectorAddress - kvp.Value, length, kvp.Key); - throw new ArgumentOutOfRangeException(nameof(sectorAddress), $"Sector address {sectorAddress} not found"); + return ErrorNumber.NoError; + } + + return ErrorNumber.SectorNotFound; } /// diff --git a/Aaru.Images/CDRWin/Read.cs b/Aaru.Images/CDRWin/Read.cs index 0651a60c0..9ec162807 100644 --- a/Aaru.Images/CDRWin/Read.cs +++ b/Aaru.Images/CDRWin/Read.cs @@ -1580,7 +1580,8 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSector(ulong sectorAddress) => ReadSectors(sectorAddress, 1); + public ErrorNumber ReadSector(ulong sectorAddress, out byte[] buffer) => + ReadSectors(sectorAddress, 1, out buffer); /// public byte[] ReadSectorTag(ulong sectorAddress, SectorTagType tag) => ReadSectorsTag(sectorAddress, 1, tag); @@ -1593,15 +1594,21 @@ namespace Aaru.DiscImages ReadSectorsTag(sectorAddress, 1, track, tag); /// - public byte[] ReadSectors(ulong sectorAddress, uint length) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, out byte[] buffer) { + buffer = null; + foreach(KeyValuePair kvp in from kvp in _offsetMap where sectorAddress >= kvp.Value from cdrwinTrack in _discImage.Tracks where cdrwinTrack.Sequence == kvp.Key where sectorAddress - kvp.Value < cdrwinTrack.Sectors select kvp) - return ReadSectors(sectorAddress - kvp.Value, length, kvp.Key); + { + buffer = ReadSectors(sectorAddress - kvp.Value, length, kvp.Key); - throw new ArgumentOutOfRangeException(nameof(sectorAddress), "Sector address not found"); + return ErrorNumber.NoError; + } + + return ErrorNumber.SectorNotFound; } /// diff --git a/Aaru.Images/CHD/Read.cs b/Aaru.Images/CHD/Read.cs index 8f2ba2daa..d80c495e4 100644 --- a/Aaru.Images/CHD/Read.cs +++ b/Aaru.Images/CHD/Read.cs @@ -1336,11 +1336,12 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSector(ulong sectorAddress) + public ErrorNumber ReadSector(ulong sectorAddress, out byte[] buffer) { + buffer = null; + if(sectorAddress > _imageInfo.Sectors - 1) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), - $"Sector address {sectorAddress} not found"); + return ErrorNumber.OutOfRange; var track = new Track(); uint sectorSize; @@ -1370,7 +1371,11 @@ namespace Aaru.DiscImages } if(_isHdd) - return sector; + { + buffer = sector; + + return ErrorNumber.NoError; + } uint sectorOffset; bool mode2 = false; @@ -1443,10 +1448,10 @@ namespace Aaru.DiscImages break; } - default: throw new FeatureSupportedButNotImplementedImageException("Unsupported track type"); + default: return ErrorNumber.NotSupported; } - byte[] buffer = new byte[sectorSize]; + buffer = new byte[sectorSize]; if(mode2) buffer = Sector.GetUserDataFromMode2(sector); @@ -1459,7 +1464,7 @@ namespace Aaru.DiscImages else Array.Copy(sector, sectorOffset, buffer, 0, sectorSize); - return buffer; + return ErrorNumber.NoError; } /// @@ -1719,25 +1724,31 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSectors(ulong sectorAddress, uint length) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, out byte[] buffer) { + buffer = null; + if(sectorAddress > _imageInfo.Sectors - 1) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), - $"Sector address {sectorAddress} not found"); + return ErrorNumber.OutOfRange; if(sectorAddress + length > _imageInfo.Sectors) - throw new ArgumentOutOfRangeException(nameof(length), - $"Requested more sectors ({sectorAddress + length}) than available ({_imageInfo.Sectors})"); + return ErrorNumber.OutOfRange; var ms = new MemoryStream(); for(uint i = 0; i < length; i++) { - byte[] sector = ReadSector(sectorAddress + i); + ErrorNumber errno = ReadSector(sectorAddress + i, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return errno; + ms.Write(sector, 0, sector.Length); } - return ms.ToArray(); + buffer = ms.ToArray(); + + return ErrorNumber.NoError; } /// @@ -1765,8 +1776,14 @@ namespace Aaru.DiscImages /// public byte[] ReadSectorLong(ulong sectorAddress) { + byte[] buffer; + if(_isHdd) - return ReadSector(sectorAddress); + { + ErrorNumber errno = ReadSector(sectorAddress, out buffer); + + return errno == ErrorNumber.NoError ? buffer : null; + } if(sectorAddress > _imageInfo.Sectors - 1) throw new ArgumentOutOfRangeException(nameof(sectorAddress), @@ -1793,7 +1810,7 @@ namespace Aaru.DiscImages _sectorCache.Add(sectorAddress, sector); } - byte[] buffer = new byte[track.RawBytesPerSector]; + buffer = new byte[track.RawBytesPerSector]; if(track.Type == TrackType.Audio && _swapAudio) for(int i = 0; i < 2352; i += 2) @@ -1925,7 +1942,9 @@ namespace Aaru.DiscImages if(_isHdd) throw new FeaturedNotSupportedByDiscImageException("Cannot access optical tracks on a hard disk image"); - return ReadSector(GetAbsoluteSector(sectorAddress, track)); + ErrorNumber errno = ReadSector(GetAbsoluteSector(sectorAddress, track), out byte[] buffer); + + return errno == ErrorNumber.NoError ? buffer : null; } /// @@ -1943,7 +1962,9 @@ namespace Aaru.DiscImages if(_isHdd) throw new FeaturedNotSupportedByDiscImageException("Cannot access optical tracks on a hard disk image"); - return ReadSectors(GetAbsoluteSector(sectorAddress, track), length); + ErrorNumber errno = ReadSectors(GetAbsoluteSector(sectorAddress, track), length, out byte[] buffer); + + return errno == ErrorNumber.NoError ? buffer : null; } /// diff --git a/Aaru.Images/CPCDSK/Read.cs b/Aaru.Images/CPCDSK/Read.cs index c7287b429..2398ea294 100644 --- a/Aaru.Images/CPCDSK/Read.cs +++ b/Aaru.Images/CPCDSK/Read.cs @@ -289,33 +289,35 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSector(ulong sectorAddress) - { - if(_sectors.TryGetValue(sectorAddress, out byte[] sector)) - return sector; - - throw new ArgumentOutOfRangeException(nameof(sectorAddress), $"Sector address {sectorAddress} not found"); - } + public ErrorNumber ReadSector(ulong sectorAddress, out byte[] buffer) => + _sectors.TryGetValue(sectorAddress, out buffer) ? ErrorNumber.NoError : ErrorNumber.SectorNotFound; /// - public byte[] ReadSectors(ulong sectorAddress, uint length) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, out byte[] buffer) { + buffer = null; + if(sectorAddress > _imageInfo.Sectors - 1) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), - $"Sector address {sectorAddress} not found"); + return ErrorNumber.OutOfRange; if(sectorAddress + length > _imageInfo.Sectors) - throw new ArgumentOutOfRangeException(nameof(length), "Requested more sectors than available"); + return ErrorNumber.OutOfRange; var ms = new MemoryStream(); for(uint i = 0; i < length; i++) { - byte[] sector = ReadSector(sectorAddress + i); + ErrorNumber errno = ReadSector(sectorAddress + i, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return errno; + ms.Write(sector, 0, sector.Length); } - return ms.ToArray(); + buffer = ms.ToArray(); + + return ErrorNumber.NoError; } /// @@ -347,7 +349,11 @@ namespace Aaru.DiscImages for(uint i = 0; i < length; i++) { - byte[] addressMark = ReadSector(sectorAddress + i); + ErrorNumber errno = ReadSector(sectorAddress + i, out byte[] addressMark); + + if(errno != ErrorNumber.NoError) + return null; + ms.Write(addressMark, 0, addressMark.Length); } diff --git a/Aaru.Images/CisCopy/Read.cs b/Aaru.Images/CisCopy/Read.cs index c2f0b3da5..7dd98746e 100644 --- a/Aaru.Images/CisCopy/Read.cs +++ b/Aaru.Images/CisCopy/Read.cs @@ -201,23 +201,26 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSector(ulong sectorAddress) => ReadSectors(sectorAddress, 1); + public ErrorNumber ReadSector(ulong sectorAddress, out byte[] buffer) => + ReadSectors(sectorAddress, 1, out buffer); /// - public byte[] ReadSectors(ulong sectorAddress, uint length) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, out byte[] buffer) { + buffer = null; + if(sectorAddress > _imageInfo.Sectors - 1) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), "Sector address not found"); + return ErrorNumber.OutOfRange; if(sectorAddress + length > _imageInfo.Sectors) - throw new ArgumentOutOfRangeException(nameof(length), "Requested more sectors than available"); + return ErrorNumber.OutOfRange; - byte[] buffer = new byte[length * _imageInfo.SectorSize]; + buffer = new byte[length * _imageInfo.SectorSize]; Array.Copy(_decodedDisk, (int)sectorAddress * _imageInfo.SectorSize, buffer, 0, length * _imageInfo.SectorSize); - return buffer; + return ErrorNumber.NoError; } } } \ No newline at end of file diff --git a/Aaru.Images/CloneCD/Read.cs b/Aaru.Images/CloneCD/Read.cs index 14eb1d909..d869b8e99 100644 --- a/Aaru.Images/CloneCD/Read.cs +++ b/Aaru.Images/CloneCD/Read.cs @@ -929,7 +929,8 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSector(ulong sectorAddress) => ReadSectors(sectorAddress, 1); + public ErrorNumber ReadSector(ulong sectorAddress, out byte[] buffer) => + ReadSectors(sectorAddress, 1, out buffer); /// public byte[] ReadSectorTag(ulong sectorAddress, SectorTagType tag) => ReadSectorsTag(sectorAddress, 1, tag); @@ -942,15 +943,21 @@ namespace Aaru.DiscImages ReadSectorsTag(sectorAddress, 1, track, tag); /// - public byte[] ReadSectors(ulong sectorAddress, uint length) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, out byte[] buffer) { + buffer = null; + foreach(KeyValuePair kvp in from kvp in _offsetMap where sectorAddress >= kvp.Value from track in Tracks where track.Sequence == kvp.Key where sectorAddress - kvp.Value < track.EndSector - track.StartSector + 1 select kvp) - return ReadSectors(sectorAddress - kvp.Value, length, kvp.Key); + { + buffer = ReadSectors(sectorAddress - kvp.Value, length, kvp.Key); - throw new ArgumentOutOfRangeException(nameof(sectorAddress), $"Sector address {sectorAddress} not found"); + return ErrorNumber.NoError; + } + + return ErrorNumber.SectorNotFound; } /// diff --git a/Aaru.Images/CopyQM/Read.cs b/Aaru.Images/CopyQM/Read.cs index c6ffe71fc..f3bfa7ce3 100644 --- a/Aaru.Images/CopyQM/Read.cs +++ b/Aaru.Images/CopyQM/Read.cs @@ -196,23 +196,26 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSector(ulong sectorAddress) => ReadSectors(sectorAddress, 1); + public ErrorNumber ReadSector(ulong sectorAddress, out byte[] buffer) => + ReadSectors(sectorAddress, 1, out buffer); /// - public byte[] ReadSectors(ulong sectorAddress, uint length) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, out byte[] buffer) { + buffer = null; + if(sectorAddress > _imageInfo.Sectors - 1) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), "Sector address not found"); + return ErrorNumber.OutOfRange; if(sectorAddress + length > _imageInfo.Sectors) - throw new ArgumentOutOfRangeException(nameof(length), "Requested more sectors than available"); + return ErrorNumber.OutOfRange; - byte[] buffer = new byte[length * _imageInfo.SectorSize]; + buffer = new byte[length * _imageInfo.SectorSize]; Array.Copy(_decodedDisk, (int)sectorAddress * _imageInfo.SectorSize, buffer, 0, length * _imageInfo.SectorSize); - return buffer; + return ErrorNumber.NoError; } /// diff --git a/Aaru.Images/CopyTape/Read.cs b/Aaru.Images/CopyTape/Read.cs index eebbc9a7b..b509957bd 100644 --- a/Aaru.Images/CopyTape/Read.cs +++ b/Aaru.Images/CopyTape/Read.cs @@ -30,7 +30,6 @@ // Copyright © 2011-2021 Natalia Portillo // ****************************************************************************/ -using System; using System.Collections.Generic; using System.IO; using System.Text; @@ -190,11 +189,12 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSector(ulong sectorAddress) + public ErrorNumber ReadSector(ulong sectorAddress, out byte[] buffer) { + buffer = null; + if(sectorAddress >= (ulong)_blockPositionCache.LongLength) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), - $"Sector address {sectorAddress} not found"); + return ErrorNumber.OutOfRange; _imageStream.Position = _blockPositionCache[sectorAddress]; @@ -206,42 +206,47 @@ namespace Aaru.DiscImages Match blockMt = blockRx.Match(mark); if(!blockMt.Success) - throw new ArgumentException("Cannot decode block header, cannot read."); + return ErrorNumber.InvalidArgument; string blkSize = blockMt.Groups["blockSize"].Value; if(string.IsNullOrWhiteSpace(blkSize)) - throw new ArgumentException("Cannot decode block header, cannot read."); + return ErrorNumber.InvalidArgument; if(!uint.TryParse(blkSize, out uint blockSize)) - throw new ArgumentException("Cannot decode block header, cannot read."); + return ErrorNumber.InvalidArgument; if(blockSize == 0 || blockSize + 17 > _imageStream.Length) - throw new ArgumentException("Cannot decode block header, cannot read."); + return ErrorNumber.InvalidArgument; - byte[] data = new byte[blockSize]; + buffer = new byte[blockSize]; - _imageStream.Read(data, 0, (int)blockSize); + _imageStream.Read(buffer, 0, (int)blockSize); - if(_imageStream.ReadByte() != 0x0A) - throw new ArgumentException("Cannot decode block header, cannot read."); - - return data; + return _imageStream.ReadByte() != 0x0A ? ErrorNumber.InvalidArgument : ErrorNumber.NoError; } /// - public byte[] ReadSectors(ulong sectorAddress, uint length) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, out byte[] buffer) { - var dataMs = new MemoryStream(); + buffer = null; + + var ms = new MemoryStream(); for(uint i = 0; i < length; i++) { - byte[] data = ReadSector(sectorAddress + i); - dataMs.Write(data, 0, data.Length); + ErrorNumber errno = ReadSector(sectorAddress + i, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return errno; + + ms.Write(sector, 0, sector.Length); } - return dataMs.ToArray(); + buffer = ms.ToArray(); + + return ErrorNumber.NoError; } } } \ No newline at end of file diff --git a/Aaru.Images/D88/Read.cs b/Aaru.Images/D88/Read.cs index afb2734ef..1776726bd 100644 --- a/Aaru.Images/D88/Read.cs +++ b/Aaru.Images/D88/Read.cs @@ -30,7 +30,6 @@ // Copyright © 2011-2021 Natalia Portillo // ****************************************************************************/ -using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -366,23 +365,28 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSector(ulong sectorAddress) => ReadSectors(sectorAddress, 1); + public ErrorNumber ReadSector(ulong sectorAddress, out byte[] buffer) => + ReadSectors(sectorAddress, 1, out buffer); /// - public byte[] ReadSectors(ulong sectorAddress, uint length) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, out byte[] buffer) { + buffer = null; + if(sectorAddress > _imageInfo.Sectors - 1) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), "Sector address not found"); + return ErrorNumber.OutOfRange; if(sectorAddress + length > _imageInfo.Sectors) - throw new ArgumentOutOfRangeException(nameof(length), "Requested more sectors than available"); + return ErrorNumber.OutOfRange; - var buffer = new MemoryStream(); + var ms = new MemoryStream(); for(int i = 0; i < length; i++) - buffer.Write(_sectorsData[(int)sectorAddress + i], 0, _sectorsData[(int)sectorAddress + i].Length); + ms.Write(_sectorsData[(int)sectorAddress + i], 0, _sectorsData[(int)sectorAddress + i].Length); - return buffer.ToArray(); + buffer = ms.ToArray(); + + return ErrorNumber.NoError; } } } \ No newline at end of file diff --git a/Aaru.Images/DART/Read.cs b/Aaru.Images/DART/Read.cs index ed0bb5a9c..65189d4b3 100644 --- a/Aaru.Images/DART/Read.cs +++ b/Aaru.Images/DART/Read.cs @@ -324,26 +324,29 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSector(ulong sectorAddress) => ReadSectors(sectorAddress, 1); + public ErrorNumber ReadSector(ulong sectorAddress, out byte[] buffer) => + ReadSectors(sectorAddress, 1, out buffer); /// public byte[] ReadSectorTag(ulong sectorAddress, SectorTagType tag) => ReadSectorsTag(sectorAddress, 1, tag); /// - public byte[] ReadSectors(ulong sectorAddress, uint length) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, out byte[] buffer) { + buffer = null; + if(sectorAddress > _imageInfo.Sectors - 1) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), "Sector address not found"); + return ErrorNumber.OutOfRange; if(sectorAddress + length > _imageInfo.Sectors) - throw new ArgumentOutOfRangeException(nameof(length), "Requested more sectors than available"); + return ErrorNumber.OutOfRange; - byte[] buffer = new byte[length * _imageInfo.SectorSize]; + buffer = new byte[length * _imageInfo.SectorSize]; Array.Copy(_dataCache, (int)sectorAddress * _imageInfo.SectorSize, buffer, 0, length * _imageInfo.SectorSize); - return buffer; + return ErrorNumber.NoError; } /// @@ -381,7 +384,11 @@ namespace Aaru.DiscImages if(sectorAddress + length > _imageInfo.Sectors) throw new ArgumentOutOfRangeException(nameof(length), "Requested more sectors than available"); - byte[] data = ReadSectors(sectorAddress, length); + ErrorNumber errno = ReadSectors(sectorAddress, length, out byte[] data); + + if(errno != ErrorNumber.NoError) + return null; + byte[] tags = ReadSectorsTag(sectorAddress, length, SectorTagType.AppleSectorTag); byte[] buffer = new byte[data.Length + tags.Length]; diff --git a/Aaru.Images/DIM/Read.cs b/Aaru.Images/DIM/Read.cs index 0e3b4d94b..b161eda8f 100644 --- a/Aaru.Images/DIM/Read.cs +++ b/Aaru.Images/DIM/Read.cs @@ -30,7 +30,6 @@ // Copyright © 2011-2021 Natalia Portillo // ****************************************************************************/ -using System; using System.IO; using System.Linq; using System.Text; @@ -242,18 +241,21 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSector(ulong sectorAddress) => ReadSectors(sectorAddress, 1); + public ErrorNumber ReadSector(ulong sectorAddress, out byte[] buffer) => + ReadSectors(sectorAddress, 1, out buffer); /// - public byte[] ReadSectors(ulong sectorAddress, uint length) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, out byte[] buffer) { + buffer = null; + if(sectorAddress > _imageInfo.Sectors - 1) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), "Sector address not found"); + return ErrorNumber.OutOfRange; if(sectorAddress + length > _imageInfo.Sectors) - throw new ArgumentOutOfRangeException(nameof(length), "Requested more sectors than available"); + return ErrorNumber.OutOfRange; - byte[] buffer = new byte[length * _imageInfo.SectorSize]; + buffer = new byte[length * _imageInfo.SectorSize]; Stream stream = _dimImageFilter.GetDataForkStream(); @@ -261,7 +263,7 @@ namespace Aaru.DiscImages stream.Read(buffer, 0, (int)(length * _imageInfo.SectorSize)); - return buffer; + return ErrorNumber.NoError; } } } \ No newline at end of file diff --git a/Aaru.Images/DiscFerret/Read.cs b/Aaru.Images/DiscFerret/Read.cs index 7c7691608..9d7a0a3fc 100644 --- a/Aaru.Images/DiscFerret/Read.cs +++ b/Aaru.Images/DiscFerret/Read.cs @@ -135,15 +135,19 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSector(ulong sectorAddress) => ReadSectors(sectorAddress, 1); + public ErrorNumber ReadSector(ulong sectorAddress, out byte[] buffer) => ReadSectors(sectorAddress, 1, out buffer); /// public byte[] ReadSectorTag(ulong sectorAddress, SectorTagType tag) => throw new NotImplementedException("Flux decoding is not yet implemented."); /// - public byte[] ReadSectors(ulong sectorAddress, uint length) => - throw new NotImplementedException("Flux decoding is not yet implemented."); + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, out byte[] buffer) + { + buffer = null; + + return ErrorNumber.NotImplemented; + } /// public byte[] ReadSectorsTag(ulong sectorAddress, uint length, SectorTagType tag) => diff --git a/Aaru.Images/DiscJuggler/Read.cs b/Aaru.Images/DiscJuggler/Read.cs index efa00ad15..cdc14943b 100644 --- a/Aaru.Images/DiscJuggler/Read.cs +++ b/Aaru.Images/DiscJuggler/Read.cs @@ -808,7 +808,8 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSector(ulong sectorAddress) => ReadSectors(sectorAddress, 1); + public ErrorNumber ReadSector(ulong sectorAddress, out byte[] buffer) => + ReadSectors(sectorAddress, 1, out buffer); /// public byte[] ReadSectorTag(ulong sectorAddress, SectorTagType tag) => ReadSectorsTag(sectorAddress, 1, tag); @@ -821,15 +822,21 @@ namespace Aaru.DiscImages ReadSectorsTag(sectorAddress, 1, track, tag); /// - public byte[] ReadSectors(ulong sectorAddress, uint length) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, out byte[] buffer) { + buffer = null; + foreach(KeyValuePair kvp in from kvp in _offsetMap where sectorAddress >= kvp.Value from track in Tracks where track.Sequence == kvp.Key where sectorAddress - kvp.Value < track.EndSector - track.StartSector + 1 select kvp) - return ReadSectors(sectorAddress - kvp.Value, length, kvp.Key); + { + buffer = ReadSectors(sectorAddress - kvp.Value, length, kvp.Key); - throw new ArgumentOutOfRangeException(nameof(sectorAddress), $"Sector address {sectorAddress} not found"); + return ErrorNumber.NoError; + } + + return ErrorNumber.SectorNotFound; } /// diff --git a/Aaru.Images/DiskCopy42/Read.cs b/Aaru.Images/DiskCopy42/Read.cs index e481ecadf..30e083bb8 100644 --- a/Aaru.Images/DiskCopy42/Read.cs +++ b/Aaru.Images/DiskCopy42/Read.cs @@ -468,21 +468,24 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSector(ulong sectorAddress) => ReadSectors(sectorAddress, 1); + public ErrorNumber ReadSector(ulong sectorAddress, out byte[] buffer) => + ReadSectors(sectorAddress, 1, out buffer); /// public byte[] ReadSectorTag(ulong sectorAddress, SectorTagType tag) => ReadSectorsTag(sectorAddress, 1, tag); /// - public byte[] ReadSectors(ulong sectorAddress, uint length) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, out byte[] buffer) { + buffer = null; + if(sectorAddress > imageInfo.Sectors - 1) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), "Sector address not found"); + return ErrorNumber.SectorNotFound; if(sectorAddress + length > imageInfo.Sectors) - throw new ArgumentOutOfRangeException(nameof(length), "Requested more sectors than available"); + return ErrorNumber.OutOfRange; - byte[] buffer = new byte[length * imageInfo.SectorSize]; + buffer = new byte[length * imageInfo.SectorSize]; if(twiggy) Array.Copy(twiggyCache, (int)sectorAddress * imageInfo.SectorSize, buffer, 0, @@ -494,7 +497,7 @@ namespace Aaru.DiscImages stream.Read(buffer, 0, (int)(length * imageInfo.SectorSize)); } - return buffer; + return ErrorNumber.NoError; } /// @@ -538,7 +541,11 @@ namespace Aaru.DiscImages if(sectorAddress + length > imageInfo.Sectors) throw new ArgumentOutOfRangeException(nameof(length), "Requested more sectors than available"); - byte[] data = ReadSectors(sectorAddress, length); + ErrorNumber errno = ReadSectors(sectorAddress, length, out byte[] data); + + if(errno != ErrorNumber.NoError) + return null; + byte[] tags = ReadSectorsTag(sectorAddress, length, SectorTagType.AppleSectorTag); byte[] buffer = new byte[data.Length + tags.Length]; diff --git a/Aaru.Images/DiskDupe/Read.cs b/Aaru.Images/DiskDupe/Read.cs index d65708e47..fd3670550 100644 --- a/Aaru.Images/DiskDupe/Read.cs +++ b/Aaru.Images/DiskDupe/Read.cs @@ -83,44 +83,59 @@ namespace Aaru.DiscImages return ErrorNumber.NoError; } - public byte[] ReadSector(ulong sectorAddress) + public ErrorNumber ReadSector(ulong sectorAddress, out byte[] buffer) { + buffer = null; int trackNum = (int)(sectorAddress / _imageInfo.SectorsPerTrack); int sectorOffset = (int)(sectorAddress % _imageInfo.SectorsPerTrack); if(sectorAddress > _imageInfo.Sectors - 1) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), "Sector address not found"); + return ErrorNumber.OutOfRange; if(trackNum > 2 * _imageInfo.Cylinders) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), "Sector address not found"); + return ErrorNumber.SectorNotFound; - byte[] result = new byte[_imageInfo.SectorSize]; + buffer = new byte[_imageInfo.SectorSize]; if(_trackMap[trackNum].present != 1) - Array.Clear(result, 0, (int)_imageInfo.SectorSize); + Array.Clear(buffer, 0, (int)_imageInfo.SectorSize); else { Stream strm = _ddiImageFilter.GetDataForkStream(); strm.Seek(_trackOffsets[trackNum] + (sectorOffset * _imageInfo.SectorSize), SeekOrigin.Begin); - strm.Read(result, 0, (int)_imageInfo.SectorSize); + strm.Read(buffer, 0, (int)_imageInfo.SectorSize); } - return result; + return ErrorNumber.NoError; } - public byte[] ReadSectors(ulong sectorAddress, uint count) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, out byte[] buffer) { - byte[] result = new byte[count * _imageInfo.SectorSize]; + buffer = null; - if(sectorAddress + count > _imageInfo.Sectors) - throw new ArgumentOutOfRangeException(nameof(count), "Requested more sectors than available"); + if(sectorAddress > _imageInfo.Sectors - 1) + return ErrorNumber.OutOfRange; - for(int i = 0; i < count; i++) - ReadSector(sectorAddress + (ulong)i).CopyTo(result, i * _imageInfo.SectorSize); + if(sectorAddress + length > _imageInfo.Sectors) + return ErrorNumber.OutOfRange; - return result; + var ms = new MemoryStream(); + + for(uint i = 0; i < length; i++) + { + ErrorNumber errno = ReadSector(sectorAddress + i, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return errno; + + ms.Write(sector, 0, sector.Length); + } + + buffer = ms.ToArray(); + + return ErrorNumber.NoError; } } } \ No newline at end of file diff --git a/Aaru.Images/DriDiskCopy/Read.cs b/Aaru.Images/DriDiskCopy/Read.cs index f8a6b1ef8..385973c21 100644 --- a/Aaru.Images/DriDiskCopy/Read.cs +++ b/Aaru.Images/DriDiskCopy/Read.cs @@ -30,7 +30,6 @@ // Copyright © 2011-2021 Natalia Portillo // ****************************************************************************/ -using System; using System.IO; using System.Text.RegularExpressions; using Aaru.CommonTypes; @@ -130,24 +129,27 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSector(ulong sectorAddress) => ReadSectors(sectorAddress, 1); + public ErrorNumber ReadSector(ulong sectorAddress, out byte[] buffer) => + ReadSectors(sectorAddress, 1, out buffer); /// - public byte[] ReadSectors(ulong sectorAddress, uint length) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, out byte[] buffer) { + buffer = null; + if(sectorAddress > _imageInfo.Sectors - 1) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), "Sector address not found"); + return ErrorNumber.OutOfRange; if(sectorAddress + length > _imageInfo.Sectors) - throw new ArgumentOutOfRangeException(nameof(length), "Requested more sectors than available"); + return ErrorNumber.OutOfRange; - byte[] buffer = new byte[length * _imageInfo.SectorSize]; + buffer = new byte[length * _imageInfo.SectorSize]; Stream stream = _driImageFilter.GetDataForkStream(); stream.Seek((long)(sectorAddress * _imageInfo.SectorSize), SeekOrigin.Begin); stream.Read(buffer, 0, (int)(length * _imageInfo.SectorSize)); - return buffer; + return ErrorNumber.NoError; } } } \ No newline at end of file diff --git a/Aaru.Images/GDI/Read.cs b/Aaru.Images/GDI/Read.cs index 2017f2101..3f9260587 100644 --- a/Aaru.Images/GDI/Read.cs +++ b/Aaru.Images/GDI/Read.cs @@ -324,7 +324,8 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSector(ulong sectorAddress) => ReadSectors(sectorAddress, 1); + public ErrorNumber ReadSector(ulong sectorAddress, out byte[] buffer) => + ReadSectors(sectorAddress, 1, out buffer); /// public byte[] ReadSectorTag(ulong sectorAddress, SectorTagType tag) => ReadSectorsTag(sectorAddress, 1, tag); @@ -337,21 +338,29 @@ namespace Aaru.DiscImages ReadSectorsTag(sectorAddress, 1, track, tag); /// - public byte[] ReadSectors(ulong sectorAddress, uint length) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, out byte[] buffer) { + buffer = null; + foreach(KeyValuePair kvp in from kvp in _offsetMap where sectorAddress >= kvp.Value from gdiTrack in _discImage.Tracks where gdiTrack.Sequence == kvp.Key where sectorAddress - kvp.Value < gdiTrack.Sectors select kvp) - return ReadSectors(sectorAddress - kvp.Value, length, kvp.Key); + { + buffer = ReadSectors(sectorAddress - kvp.Value, length, kvp.Key); + + return ErrorNumber.NoError; + } _offsetMap.TryGetValue(0, out ulong transitionStart); - if(sectorAddress >= transitionStart && - sectorAddress < _densitySeparationSectors + transitionStart) - return ReadSectors(sectorAddress - transitionStart, length, 0); + if(sectorAddress < transitionStart || + sectorAddress >= _densitySeparationSectors + transitionStart) + return ErrorNumber.SectorNotFound; - throw new ArgumentOutOfRangeException(nameof(sectorAddress), "Sector address not found"); + buffer = ReadSectors(sectorAddress - transitionStart, length, 0); + + return ErrorNumber.NoError; } /// diff --git a/Aaru.Images/HDCopy/Read.cs b/Aaru.Images/HDCopy/Read.cs index f7f84cb87..2c638d84b 100644 --- a/Aaru.Images/HDCopy/Read.cs +++ b/Aaru.Images/HDCopy/Read.cs @@ -117,46 +117,61 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSector(ulong sectorAddress) + public ErrorNumber ReadSector(ulong sectorAddress, out byte[] buffer) { + buffer = null; int trackNum = (int)(sectorAddress / _imageInfo.SectorsPerTrack); int sectorOffset = (int)(sectorAddress % _imageInfo.SectorsPerTrack); if(sectorAddress > _imageInfo.Sectors - 1) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), "Sector address not found"); + return ErrorNumber.OutOfRange; if(trackNum > 2 * _imageInfo.Cylinders) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), "Sector address not found"); + return ErrorNumber.SectorNotFound; - byte[] result = new byte[_imageInfo.SectorSize]; + buffer = new byte[_imageInfo.SectorSize]; if(_trackOffset[trackNum] == -1) - Array.Clear(result, 0, (int)_imageInfo.SectorSize); + Array.Clear(buffer, 0, (int)_imageInfo.SectorSize); else { // track is present in file, make sure it has been loaded if(!_trackCache.ContainsKey(trackNum)) ReadTrackIntoCache(_hdcpImageFilter.GetDataForkStream(), trackNum); - Array.Copy(_trackCache[trackNum], sectorOffset * _imageInfo.SectorSize, result, 0, + Array.Copy(_trackCache[trackNum], sectorOffset * _imageInfo.SectorSize, buffer, 0, _imageInfo.SectorSize); } - return result; + return ErrorNumber.NoError; } /// - public byte[] ReadSectors(ulong sectorAddress, uint length) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, out byte[] buffer) { - byte[] result = new byte[length * _imageInfo.SectorSize]; + buffer = null; + + if(sectorAddress > _imageInfo.Sectors - 1) + return ErrorNumber.OutOfRange; if(sectorAddress + length > _imageInfo.Sectors) - throw new ArgumentOutOfRangeException(nameof(length), "Requested more sectors than available"); + return ErrorNumber.OutOfRange; - for(int i = 0; i < length; i++) - ReadSector(sectorAddress + (ulong)i).CopyTo(result, i * _imageInfo.SectorSize); + var ms = new MemoryStream(); - return result; + for(uint i = 0; i < length; i++) + { + ErrorNumber errno = ReadSector(sectorAddress + i, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return errno; + + ms.Write(sector, 0, sector.Length); + } + + buffer = ms.ToArray(); + + return ErrorNumber.NoError; } } } \ No newline at end of file diff --git a/Aaru.Images/IMD/Read.cs b/Aaru.Images/IMD/Read.cs index 9eeb837c9..690c20d8d 100644 --- a/Aaru.Images/IMD/Read.cs +++ b/Aaru.Images/IMD/Read.cs @@ -217,23 +217,26 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSector(ulong sectorAddress) => ReadSectors(sectorAddress, 1); + public ErrorNumber ReadSector(ulong sectorAddress, out byte[] buffer) => ReadSectors(sectorAddress, 1, out buffer); /// - public byte[] ReadSectors(ulong sectorAddress, uint length) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, out byte[] buffer) { + buffer = null; if(sectorAddress > _imageInfo.Sectors - 1) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), "Sector address not found"); + return ErrorNumber.OutOfRange; if(sectorAddress + length > _imageInfo.Sectors) - throw new ArgumentOutOfRangeException(nameof(length), "Requested more sectors than available"); + return ErrorNumber.OutOfRange; - var buffer = new MemoryStream(); + var ms = new MemoryStream(); for(int i = 0; i < length; i++) - buffer.Write(_sectorsData[(int)sectorAddress + i], 0, _sectorsData[(int)sectorAddress + i].Length); + ms.Write(_sectorsData[(int)sectorAddress + i], 0, _sectorsData[(int)sectorAddress + i].Length); - return buffer.ToArray(); + buffer = ms.ToArray(); + + return ErrorNumber.NoError; } } } \ No newline at end of file diff --git a/Aaru.Images/KryoFlux/Read.cs b/Aaru.Images/KryoFlux/Read.cs index 0dbf1821d..0d58e4310 100644 --- a/Aaru.Images/KryoFlux/Read.cs +++ b/Aaru.Images/KryoFlux/Read.cs @@ -264,15 +264,20 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSector(ulong sectorAddress) => ReadSectors(sectorAddress, 1); + public ErrorNumber ReadSector(ulong sectorAddress, out byte[] buffer) => + ReadSectors(sectorAddress, 1, out buffer); /// public byte[] ReadSectorTag(ulong sectorAddress, SectorTagType tag) => throw new NotImplementedException("Flux decoding is not yet implemented."); /// - public byte[] ReadSectors(ulong sectorAddress, uint length) => - throw new NotImplementedException("Flux decoding is not yet implemented."); + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, out byte[] buffer) + { + buffer = null; + + return ErrorNumber.NotImplemented; + } /// public byte[] ReadSectorsTag(ulong sectorAddress, uint length, SectorTagType tag) => diff --git a/Aaru.Images/MaxiDisk/Read.cs b/Aaru.Images/MaxiDisk/Read.cs index f41620b2b..ceb9d9dc0 100644 --- a/Aaru.Images/MaxiDisk/Read.cs +++ b/Aaru.Images/MaxiDisk/Read.cs @@ -30,7 +30,6 @@ // Copyright © 2011-2021 Natalia Portillo // ****************************************************************************/ -using System; using System.IO; using Aaru.CommonTypes; using Aaru.CommonTypes.Enums; @@ -101,24 +100,27 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSector(ulong sectorAddress) => ReadSectors(sectorAddress, 1); + public ErrorNumber ReadSector(ulong sectorAddress, out byte[] buffer) => + ReadSectors(sectorAddress, 1, out buffer); /// - public byte[] ReadSectors(ulong sectorAddress, uint length) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, out byte[] buffer) { + buffer = null; + if(sectorAddress > _imageInfo.Sectors - 1) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), "Sector address not found"); + return ErrorNumber.OutOfRange; if(sectorAddress + length > _imageInfo.Sectors) - throw new ArgumentOutOfRangeException(nameof(length), "Requested more sectors than available"); + return ErrorNumber.OutOfRange; - byte[] buffer = new byte[length * _imageInfo.SectorSize]; + buffer = new byte[length * _imageInfo.SectorSize]; Stream stream = _hdkImageFilter.GetDataForkStream(); stream.Seek((long)(8 + (sectorAddress * _imageInfo.SectorSize)), SeekOrigin.Begin); stream.Read(buffer, 0, (int)(length * _imageInfo.SectorSize)); - return buffer; + return ErrorNumber.NoError; } } } \ No newline at end of file diff --git a/Aaru.Images/NDIF/Read.cs b/Aaru.Images/NDIF/Read.cs index 24417bb9e..50f8853ed 100644 --- a/Aaru.Images/NDIF/Read.cs +++ b/Aaru.Images/NDIF/Read.cs @@ -314,14 +314,15 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSector(ulong sectorAddress) + public ErrorNumber ReadSector(ulong sectorAddress, out byte[] buffer) { - if(sectorAddress > _imageInfo.Sectors - 1) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), - $"Sector address {sectorAddress} not found"); + buffer = null; - if(_sectorCache.TryGetValue(sectorAddress, out byte[] sector)) - return sector; + if(sectorAddress > _imageInfo.Sectors - 1) + return ErrorNumber.OutOfRange; + + if(_sectorCache.TryGetValue(sectorAddress, out buffer)) + return ErrorNumber.NoError; var currentChunk = new BlockChunk(); bool chunkFound = false; @@ -337,16 +338,14 @@ namespace Aaru.DiscImages long relOff = ((long)sectorAddress - (long)chunkStartSector) * SECTOR_SIZE; if(relOff < 0) - throw new ArgumentOutOfRangeException(nameof(relOff), - $"Got a negative offset for sector {sectorAddress}. This should not happen."); + return ErrorNumber.InvalidArgument; if(!chunkFound) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), - $"Sector address {sectorAddress} not found"); + return ErrorNumber.SectorNotFound; if((currentChunk.type & CHUNK_TYPE_COMPRESSED_MASK) == CHUNK_TYPE_COMPRESSED_MASK) { - if(!_chunkCache.TryGetValue(chunkStartSector, out byte[] buffer)) + if(!_chunkCache.TryGetValue(chunkStartSector, out byte[] data)) { byte[] cmpBuffer = new byte[currentChunk.length]; _imageStream.Seek(currentChunk.offset, SeekOrigin.Begin); @@ -361,8 +360,8 @@ namespace Aaru.DiscImages Stream decStream = new ADCStream(cmpMs); byte[] tmpBuffer = new byte[_bufferSize]; realSize = decStream.Read(tmpBuffer, 0, (int)_bufferSize); - buffer = new byte[realSize]; - Array.Copy(tmpBuffer, 0, buffer, 0, realSize); + data = new byte[realSize]; + Array.Copy(tmpBuffer, 0, data, 0, realSize); break; } @@ -384,15 +383,13 @@ namespace Aaru.DiscImages realSize++; } - buffer = new byte[realSize]; - Array.Copy(tmpBuffer, 0, buffer, 0, realSize); + data = new byte[realSize]; + Array.Copy(tmpBuffer, 0, data, 0, realSize); break; } - default: - throw new - ImageNotSupportedException($"Unsupported chunk type 0x{currentChunk.type:X8} found"); + default: return ErrorNumber.NotSupported; } if(_currentChunkCacheSize + realSize > MAX_CACHE_SIZE) @@ -401,67 +398,74 @@ namespace Aaru.DiscImages _currentChunkCacheSize = 0; } - _chunkCache.Add(chunkStartSector, buffer); + _chunkCache.Add(chunkStartSector, data); _currentChunkCacheSize += (uint)realSize; } - sector = new byte[SECTOR_SIZE]; - Array.Copy(buffer, relOff, sector, 0, SECTOR_SIZE); + buffer = new byte[SECTOR_SIZE]; + Array.Copy(data, relOff, buffer, 0, SECTOR_SIZE); if(_sectorCache.Count >= MAX_CACHED_SECTORS) _sectorCache.Clear(); - _sectorCache.Add(sectorAddress, sector); + _sectorCache.Add(sectorAddress, buffer); - return sector; + return ErrorNumber.NoError; } switch(currentChunk.type) { case CHUNK_TYPE_NOCOPY: - sector = new byte[SECTOR_SIZE]; + buffer = new byte[SECTOR_SIZE]; if(_sectorCache.Count >= MAX_CACHED_SECTORS) _sectorCache.Clear(); - _sectorCache.Add(sectorAddress, sector); + _sectorCache.Add(sectorAddress, buffer); - return sector; + return ErrorNumber.NoError; case CHUNK_TYPE_COPY: _imageStream.Seek(currentChunk.offset + relOff, SeekOrigin.Begin); - sector = new byte[SECTOR_SIZE]; - _imageStream.Read(sector, 0, sector.Length); + buffer = new byte[SECTOR_SIZE]; + _imageStream.Read(buffer, 0, buffer.Length); if(_sectorCache.Count >= MAX_CACHED_SECTORS) _sectorCache.Clear(); - _sectorCache.Add(sectorAddress, sector); + _sectorCache.Add(sectorAddress, buffer); - return sector; + return ErrorNumber.NoError; } - throw new ImageNotSupportedException($"Unsupported chunk type 0x{currentChunk.type:X8} found"); + return ErrorNumber.NotSupported; } /// - public byte[] ReadSectors(ulong sectorAddress, uint length) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, out byte[] buffer) { + buffer = null; + if(sectorAddress > _imageInfo.Sectors - 1) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), - $"Sector address {sectorAddress} not found"); + return ErrorNumber.OutOfRange; if(sectorAddress + length > _imageInfo.Sectors) - throw new ArgumentOutOfRangeException(nameof(length), "Requested more sectors than available"); + return ErrorNumber.OutOfRange; var ms = new MemoryStream(); for(uint i = 0; i < length; i++) { - byte[] sector = ReadSector(sectorAddress + i); + ErrorNumber errno = ReadSector(sectorAddress + i, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return errno; + ms.Write(sector, 0, sector.Length); } - return ms.ToArray(); + buffer = ms.ToArray(); + + return ErrorNumber.NoError; } } } \ No newline at end of file diff --git a/Aaru.Images/NHDr0/Read.cs b/Aaru.Images/NHDr0/Read.cs index 49f52e05f..10fb2d0fc 100644 --- a/Aaru.Images/NHDr0/Read.cs +++ b/Aaru.Images/NHDr0/Read.cs @@ -30,7 +30,6 @@ // Copyright © 2011-2021 Natalia Portillo // ****************************************************************************/ -using System; using System.IO; using System.Text; using Aaru.CommonTypes; @@ -79,18 +78,21 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSector(ulong sectorAddress) => ReadSectors(sectorAddress, 1); + public ErrorNumber ReadSector(ulong sectorAddress, out byte[] buffer) => + ReadSectors(sectorAddress, 1, out buffer); /// - public byte[] ReadSectors(ulong sectorAddress, uint length) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, out byte[] buffer) { + buffer = null; + if(sectorAddress > _imageInfo.Sectors - 1) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), "Sector address not found"); + return ErrorNumber.OutOfRange; if(sectorAddress + length > _imageInfo.Sectors) - throw new ArgumentOutOfRangeException(nameof(length), "Requested more sectors than available"); + return ErrorNumber.OutOfRange; - byte[] buffer = new byte[length * _imageInfo.SectorSize]; + buffer = new byte[length * _imageInfo.SectorSize]; Stream stream = _nhdImageFilter.GetDataForkStream(); @@ -98,7 +100,7 @@ namespace Aaru.DiscImages stream.Read(buffer, 0, (int)(length * _imageInfo.SectorSize)); - return buffer; + return ErrorNumber.NoError; } } } \ No newline at end of file diff --git a/Aaru.Images/Nero/Read.cs b/Aaru.Images/Nero/Read.cs index 5f059c71c..df560bf84 100644 --- a/Aaru.Images/Nero/Read.cs +++ b/Aaru.Images/Nero/Read.cs @@ -1585,7 +1585,8 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSector(ulong sectorAddress) => ReadSectors(sectorAddress, 1); + public ErrorNumber ReadSector(ulong sectorAddress, out byte[] buffer) => + ReadSectors(sectorAddress, 1, out buffer); /// public byte[] ReadSectorTag(ulong sectorAddress, SectorTagType tag) => ReadSectorsTag(sectorAddress, 1, tag); @@ -1598,15 +1599,21 @@ namespace Aaru.DiscImages ReadSectorsTag(sectorAddress, 1, track, tag); /// - public byte[] ReadSectors(ulong sectorAddress, uint length) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, out byte[] buffer) { + buffer = null; + foreach(KeyValuePair kvp in from kvp in _offsetmap where sectorAddress >= kvp.Value from track in Tracks where track.Sequence == kvp.Key where sectorAddress - kvp.Value <= track.EndSector - track.StartSector select kvp) - return ReadSectors(sectorAddress - kvp.Value, length, kvp.Key); + { + buffer = ReadSectors(sectorAddress - kvp.Value, length, kvp.Key); - throw new ArgumentOutOfRangeException(nameof(sectorAddress), $"Sector address {sectorAddress} not found"); + return ErrorNumber.NoError; + } + + return ErrorNumber.SectorNotFound; } /// diff --git a/Aaru.Images/Parallels/Read.cs b/Aaru.Images/Parallels/Read.cs index b4ae72ad5..6a96e0dbe 100644 --- a/Aaru.Images/Parallels/Read.cs +++ b/Aaru.Images/Parallels/Read.cs @@ -108,17 +108,23 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSector(ulong sectorAddress) + public ErrorNumber ReadSector(ulong sectorAddress, out byte[] buffer) { + buffer = null; + if(sectorAddress > _imageInfo.Sectors - 1) throw new ArgumentOutOfRangeException(nameof(sectorAddress), $"Sector address {sectorAddress} not found"); if(_empty) - return new byte[512]; + { + buffer = new byte[512]; - if(_sectorCache.TryGetValue(sectorAddress, out byte[] sector)) - return sector; + return ErrorNumber.NoError; + } + + if(_sectorCache.TryGetValue(sectorAddress, out buffer)) + return ErrorNumber.NoError; ulong index = sectorAddress / _pHdr.cluster_size; ulong secOff = sectorAddress % _pHdr.cluster_size; @@ -127,7 +133,11 @@ namespace Aaru.DiscImages ulong imageOff; if(batOff == 0) - return new byte[512]; + { + buffer = new byte[512]; + + return ErrorNumber.NoError; + } if(_extended) imageOff = (ulong)batOff * _clusterBytes; @@ -137,39 +147,43 @@ namespace Aaru.DiscImages byte[] cluster = new byte[_clusterBytes]; _imageStream.Seek((long)imageOff, SeekOrigin.Begin); _imageStream.Read(cluster, 0, (int)_clusterBytes); - sector = new byte[512]; - Array.Copy(cluster, (int)(secOff * 512), sector, 0, 512); + buffer = new byte[512]; + Array.Copy(cluster, (int)(secOff * 512), buffer, 0, 512); if(_sectorCache.Count > MAX_CACHED_SECTORS) _sectorCache.Clear(); - _sectorCache.Add(sectorAddress, sector); + _sectorCache.Add(sectorAddress, buffer); - return sector; + return ErrorNumber.NoError; } /// - public byte[] ReadSectors(ulong sectorAddress, uint length) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, out byte[] buffer) { + buffer = null; + if(sectorAddress > _imageInfo.Sectors - 1) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), - $"Sector address {sectorAddress} not found"); + return ErrorNumber.OutOfRange; if(sectorAddress + length > _imageInfo.Sectors) - throw new ArgumentOutOfRangeException(nameof(length), "Requested more sectors than available"); - - if(_empty) - return new byte[512 * length]; + return ErrorNumber.OutOfRange; var ms = new MemoryStream(); for(uint i = 0; i < length; i++) { - byte[] sector = ReadSector(sectorAddress + i); + ErrorNumber errno = ReadSector(sectorAddress + i, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return errno; + ms.Write(sector, 0, sector.Length); } - return ms.ToArray(); + buffer = ms.ToArray(); + + return ErrorNumber.NoError; } } } \ No newline at end of file diff --git a/Aaru.Images/PartClone/Read.cs b/Aaru.Images/PartClone/Read.cs index 2cd8c46e0..8952b1314 100644 --- a/Aaru.Images/PartClone/Read.cs +++ b/Aaru.Images/PartClone/Read.cs @@ -139,41 +139,47 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSector(ulong sectorAddress) + public ErrorNumber ReadSector(ulong sectorAddress, out byte[] buffer) { + buffer = null; + if(sectorAddress > _imageInfo.Sectors - 1) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), - $"Sector address {sectorAddress} not found"); + return ErrorNumber.OutOfRange; if(_byteMap[sectorAddress] == 0) - return new byte[_pHdr.blockSize]; + { + buffer = new byte[_pHdr.blockSize]; - if(_sectorCache.TryGetValue(sectorAddress, out byte[] sector)) - return sector; + return ErrorNumber.NoError; + } + + if(_sectorCache.TryGetValue(sectorAddress, out buffer)) + return ErrorNumber.NoError; long imageOff = _dataOff + (long)(BlockOffset(sectorAddress) * (_pHdr.blockSize + CRC_SIZE)); - sector = new byte[_pHdr.blockSize]; + buffer = new byte[_pHdr.blockSize]; _imageStream.Seek(imageOff, SeekOrigin.Begin); - _imageStream.Read(sector, 0, (int)_pHdr.blockSize); + _imageStream.Read(buffer, 0, (int)_pHdr.blockSize); if(_sectorCache.Count > MAX_CACHED_SECTORS) _sectorCache.Clear(); - _sectorCache.Add(sectorAddress, sector); + _sectorCache.Add(sectorAddress, buffer); - return sector; + return ErrorNumber.NoError; } /// - public byte[] ReadSectors(ulong sectorAddress, uint length) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, out byte[] buffer) { + buffer = null; + if(sectorAddress > _imageInfo.Sectors - 1) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), - $"Sector address {sectorAddress} not found"); + return ErrorNumber.OutOfRange; if(sectorAddress + length > _imageInfo.Sectors) - throw new ArgumentOutOfRangeException(nameof(length), "Requested more sectors than available"); + return ErrorNumber.OutOfRange; var ms = new MemoryStream(); @@ -188,15 +194,25 @@ namespace Aaru.DiscImages } if(allEmpty) - return new byte[_pHdr.blockSize * length]; + { + buffer = new byte[_pHdr.blockSize * length]; + + return ErrorNumber.NoError; + } for(uint i = 0; i < length; i++) { - byte[] sector = ReadSector(sectorAddress + i); + ErrorNumber errno = ReadSector(sectorAddress + i, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return errno; + ms.Write(sector, 0, sector.Length); } - return ms.ToArray(); + buffer = ms.ToArray(); + + return ErrorNumber.NoError; } } } \ No newline at end of file diff --git a/Aaru.Images/Partimage/Read.cs b/Aaru.Images/Partimage/Read.cs index 2cb2e5f00..98e6b8bfd 100644 --- a/Aaru.Images/Partimage/Read.cs +++ b/Aaru.Images/Partimage/Read.cs @@ -353,17 +353,22 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSector(ulong sectorAddress) + public ErrorNumber ReadSector(ulong sectorAddress, out byte[] buffer) { + buffer = null; + if(sectorAddress > _imageInfo.Sectors - 1) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), - $"Sector address {sectorAddress} not found"); + return ErrorNumber.OutOfRange; if((_bitmap[sectorAddress / 8] & (1 << (int)(sectorAddress % 8))) == 0) - return new byte[_imageInfo.SectorSize]; + { + buffer = new byte[_imageInfo.SectorSize]; - if(_sectorCache.TryGetValue(sectorAddress, out byte[] sector)) - return sector; + return ErrorNumber.NoError; + } + + if(_sectorCache.TryGetValue(sectorAddress, out buffer)) + return ErrorNumber.NoError; ulong blockOff = BlockOffset(sectorAddress); @@ -377,27 +382,28 @@ namespace Aaru.DiscImages // How many bytes of CRC blocks to skip ((long)(blockOff / (CHECK_FREQUENCY / _imageInfo.SectorSize)) * Marshal.SizeOf()); - sector = new byte[_imageInfo.SectorSize]; + buffer = new byte[_imageInfo.SectorSize]; _imageStream.Seek(imageOff, SeekOrigin.Begin); - _imageStream.Read(sector, 0, (int)_imageInfo.SectorSize); + _imageStream.Read(buffer, 0, (int)_imageInfo.SectorSize); if(_sectorCache.Count > MAX_CACHED_SECTORS) _sectorCache.Clear(); - _sectorCache.Add(sectorAddress, sector); + _sectorCache.Add(sectorAddress, buffer); - return sector; + return ErrorNumber.NoError; } /// - public byte[] ReadSectors(ulong sectorAddress, uint length) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, out byte[] buffer) { + buffer = null; + if(sectorAddress > _imageInfo.Sectors - 1) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), - $"Sector address {sectorAddress} not found"); + return ErrorNumber.OutOfRange; if(sectorAddress + length > _imageInfo.Sectors) - throw new ArgumentOutOfRangeException(nameof(length), "Requested more sectors than available"); + return ErrorNumber.OutOfRange; var ms = new MemoryStream(); @@ -412,15 +418,25 @@ namespace Aaru.DiscImages } if(allEmpty) - return new byte[_imageInfo.SectorSize * length]; + { + buffer = new byte[_imageInfo.SectorSize * length]; + + return ErrorNumber.NoError; + } for(uint i = 0; i < length; i++) { - byte[] sector = ReadSector(sectorAddress + i); + ErrorNumber errno = ReadSector(sectorAddress + i, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return errno; + ms.Write(sector, 0, sector.Length); } - return ms.ToArray(); + buffer = ms.ToArray(); + + return ErrorNumber.NoError; } } } \ No newline at end of file diff --git a/Aaru.Images/QCOW/Read.cs b/Aaru.Images/QCOW/Read.cs index 5ed4cb8d9..c30f8f59e 100644 --- a/Aaru.Images/QCOW/Read.cs +++ b/Aaru.Images/QCOW/Read.cs @@ -180,27 +180,36 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSector(ulong sectorAddress) + public ErrorNumber ReadSector(ulong sectorAddress, out byte[] buffer) { + buffer = null; + if(sectorAddress > _imageInfo.Sectors - 1) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), - $"Sector address {sectorAddress} not found"); + return ErrorNumber.OutOfRange; // Check cache - if(_sectorCache.TryGetValue(sectorAddress, out byte[] sector)) - return sector; + if(_sectorCache.TryGetValue(sectorAddress, out buffer)) + return ErrorNumber.NoError; ulong byteAddress = sectorAddress * 512; ulong l1Off = (byteAddress & _l1Mask) >> _l1Shift; if((long)l1Off >= _l1Table.LongLength) - throw new ArgumentOutOfRangeException(nameof(l1Off), - $"Trying to read past L1 table, position {l1Off} of a max {_l1Table.LongLength}"); + { + AaruConsole.DebugWriteLine("QCOW plugin", + $"Trying to read past L1 table, position {l1Off} of a max {_l1Table.LongLength}"); + + return ErrorNumber.InvalidArgument; + } // TODO: Implement differential images if(_l1Table[l1Off] == 0) - return new byte[512]; + { + buffer = new byte[512]; + + return ErrorNumber.NoError; + } if(!_l2TableCache.TryGetValue(l1Off, out ulong[] l2Table)) { @@ -223,7 +232,7 @@ namespace Aaru.DiscImages ulong offset = l2Table[l2Off]; - sector = new byte[512]; + buffer = new byte[512]; if(offset != 0) { @@ -247,8 +256,7 @@ namespace Aaru.DiscImages int read = zStream.Read(cluster, 0, _clusterSize); if(read != _clusterSize) - throw new - IOException($"Unable to decompress cluster, expected {_clusterSize} bytes got {read}"); + return ErrorNumber.InOutError; } else { @@ -263,36 +271,43 @@ namespace Aaru.DiscImages _clusterCache.Add(offset, cluster); } - Array.Copy(cluster, (int)(byteAddress & _sectorMask), sector, 0, 512); + Array.Copy(cluster, (int)(byteAddress & _sectorMask), buffer, 0, 512); } if(_sectorCache.Count >= MAX_CACHED_SECTORS) _sectorCache.Clear(); - _sectorCache.Add(sectorAddress, sector); + _sectorCache.Add(sectorAddress, buffer); - return sector; + return ErrorNumber.NoError; } /// - public byte[] ReadSectors(ulong sectorAddress, uint length) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, out byte[] buffer) { + buffer = null; + if(sectorAddress > _imageInfo.Sectors - 1) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), - $"Sector address {sectorAddress} not found"); + return ErrorNumber.OutOfRange; if(sectorAddress + length > _imageInfo.Sectors) - throw new ArgumentOutOfRangeException(nameof(length), "Requested more sectors than available"); + return ErrorNumber.OutOfRange; var ms = new MemoryStream(); for(uint i = 0; i < length; i++) { - byte[] sector = ReadSector(sectorAddress + i); + ErrorNumber errno = ReadSector(sectorAddress + i, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return errno; + ms.Write(sector, 0, sector.Length); } - return ms.ToArray(); + buffer = ms.ToArray(); + + return ErrorNumber.NoError; } } } \ No newline at end of file diff --git a/Aaru.Images/QCOW2/Read.cs b/Aaru.Images/QCOW2/Read.cs index 322b0bfc4..3dfd9d9c8 100644 --- a/Aaru.Images/QCOW2/Read.cs +++ b/Aaru.Images/QCOW2/Read.cs @@ -187,27 +187,36 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSector(ulong sectorAddress) + public ErrorNumber ReadSector(ulong sectorAddress, out byte[] buffer) { + buffer = null; + if(sectorAddress > _imageInfo.Sectors - 1) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), - $"Sector address {sectorAddress} not found"); + return ErrorNumber.OutOfRange; // Check cache - if(_sectorCache.TryGetValue(sectorAddress, out byte[] sector)) - return sector; + if(_sectorCache.TryGetValue(sectorAddress, out buffer)) + return ErrorNumber.NoError; ulong byteAddress = sectorAddress * 512; ulong l1Off = (byteAddress & _l1Mask) >> _l1Shift; if((long)l1Off >= _l1Table.LongLength) - throw new ArgumentOutOfRangeException(nameof(l1Off), - $"Trying to read past L1 table, position {l1Off} of a max {_l1Table.LongLength}"); + { + AaruConsole.DebugWriteLine("QCOW2 plugin", + $"Trying to read past L1 table, position {l1Off} of a max {_l1Table.LongLength}"); + + return ErrorNumber.InvalidArgument; + } // TODO: Implement differential images if(_l1Table[l1Off] == 0) - return new byte[512]; + { + buffer = new byte[512]; + + return ErrorNumber.NoError; + } if(!_l2TableCache.TryGetValue(l1Off, out ulong[] l2Table)) { @@ -230,7 +239,7 @@ namespace Aaru.DiscImages ulong offset = l2Table[l2Off]; - sector = new byte[512]; + buffer = new byte[512]; if((offset & QCOW_FLAGS_MASK) != 0) { @@ -255,8 +264,7 @@ namespace Aaru.DiscImages int read = zStream.Read(cluster, 0, _clusterSize); if(read != _clusterSize) - throw new - IOException($"Unable to decompress cluster, expected {_clusterSize} bytes got {read}"); + return ErrorNumber.InOutError; } else { @@ -271,36 +279,43 @@ namespace Aaru.DiscImages _clusterCache.Add(offset, cluster); } - Array.Copy(cluster, (int)(byteAddress & _sectorMask), sector, 0, 512); + Array.Copy(cluster, (int)(byteAddress & _sectorMask), buffer, 0, 512); } if(_sectorCache.Count >= MAX_CACHED_SECTORS) _sectorCache.Clear(); - _sectorCache.Add(sectorAddress, sector); + _sectorCache.Add(sectorAddress, buffer); - return sector; + return ErrorNumber.NoError; } /// - public byte[] ReadSectors(ulong sectorAddress, uint length) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, out byte[] buffer) { + buffer = null; + if(sectorAddress > _imageInfo.Sectors - 1) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), - $"Sector address {sectorAddress} not found"); + return ErrorNumber.OutOfRange; if(sectorAddress + length > _imageInfo.Sectors) - throw new ArgumentOutOfRangeException(nameof(length), "Requested more sectors than available"); + return ErrorNumber.OutOfRange; var ms = new MemoryStream(); for(uint i = 0; i < length; i++) { - byte[] sector = ReadSector(sectorAddress + i); + ErrorNumber errno = ReadSector(sectorAddress + i, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return errno; + ms.Write(sector, 0, sector.Length); } - return ms.ToArray(); + buffer = ms.ToArray(); + + return ErrorNumber.NoError; } } } \ No newline at end of file diff --git a/Aaru.Images/QED/Read.cs b/Aaru.Images/QED/Read.cs index b02629a0f..c34d704bc 100644 --- a/Aaru.Images/QED/Read.cs +++ b/Aaru.Images/QED/Read.cs @@ -161,27 +161,36 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSector(ulong sectorAddress) + public ErrorNumber ReadSector(ulong sectorAddress, out byte[] buffer) { + buffer = null; + if(sectorAddress > _imageInfo.Sectors - 1) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), - $"Sector address {sectorAddress} not found"); + return ErrorNumber.OutOfRange; // Check cache - if(_sectorCache.TryGetValue(sectorAddress, out byte[] sector)) - return sector; + if(_sectorCache.TryGetValue(sectorAddress, out buffer)) + return ErrorNumber.NoError; ulong byteAddress = sectorAddress * 512; ulong l1Off = (byteAddress & _l1Mask) >> _l1Shift; if((long)l1Off >= _l1Table.LongLength) - throw new ArgumentOutOfRangeException(nameof(l1Off), - $"Trying to read past L1 table, position {l1Off} of a max {_l1Table.LongLength}"); + { + AaruConsole.DebugWriteLine("QED plugin", + $"Trying to read past L1 table, position {l1Off} of a max {_l1Table.LongLength}"); + + return ErrorNumber.InvalidArgument; + } // TODO: Implement differential images if(_l1Table[l1Off] == 0) - return new byte[512]; + { + buffer = new byte[512]; + + return ErrorNumber.NoError; + } if(!_l2TableCache.TryGetValue(l1Off, out ulong[] l2Table)) { @@ -201,7 +210,7 @@ namespace Aaru.DiscImages ulong offset = l2Table[l2Off]; - sector = new byte[512]; + buffer = new byte[512]; if(offset != 0 && offset != 1) @@ -218,36 +227,43 @@ namespace Aaru.DiscImages _clusterCache.Add(offset, cluster); } - Array.Copy(cluster, (int)(byteAddress & _sectorMask), sector, 0, 512); + Array.Copy(cluster, (int)(byteAddress & _sectorMask), buffer, 0, 512); } if(_sectorCache.Count >= MAX_CACHED_SECTORS) _sectorCache.Clear(); - _sectorCache.Add(sectorAddress, sector); + _sectorCache.Add(sectorAddress, buffer); - return sector; + return ErrorNumber.NoError; } /// - public byte[] ReadSectors(ulong sectorAddress, uint length) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, out byte[] buffer) { + buffer = null; + if(sectorAddress > _imageInfo.Sectors - 1) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), - $"Sector address {sectorAddress} not found"); + return ErrorNumber.OutOfRange; if(sectorAddress + length > _imageInfo.Sectors) - throw new ArgumentOutOfRangeException(nameof(length), "Requested more sectors than available"); + return ErrorNumber.OutOfRange; var ms = new MemoryStream(); for(uint i = 0; i < length; i++) { - byte[] sector = ReadSector(sectorAddress + i); + ErrorNumber errno = ReadSector(sectorAddress + i, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return errno; + ms.Write(sector, 0, sector.Length); } - return ms.ToArray(); + buffer = ms.ToArray(); + + return ErrorNumber.NoError; } } } \ No newline at end of file diff --git a/Aaru.Images/RayDIM/Read.cs b/Aaru.Images/RayDIM/Read.cs index f31a285e8..81bba350d 100644 --- a/Aaru.Images/RayDIM/Read.cs +++ b/Aaru.Images/RayDIM/Read.cs @@ -30,7 +30,6 @@ // Copyright © 2011-2021 Natalia Portillo // ****************************************************************************/ -using System; using System.IO; using System.Text.RegularExpressions; using Aaru.CommonTypes; @@ -110,23 +109,26 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSector(ulong sectorAddress) => ReadSectors(sectorAddress, 1); + public ErrorNumber ReadSector(ulong sectorAddress, out byte[] buffer) => + ReadSectors(sectorAddress, 1, out buffer); /// - public byte[] ReadSectors(ulong sectorAddress, uint length) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, out byte[] buffer) { + buffer = null; + if(sectorAddress > _imageInfo.Sectors - 1) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), "Sector address not found"); + return ErrorNumber.OutOfRange; if(sectorAddress + length > _imageInfo.Sectors) - throw new ArgumentOutOfRangeException(nameof(length), "Requested more sectors than available"); + return ErrorNumber.OutOfRange; - byte[] buffer = new byte[length * _imageInfo.SectorSize]; + buffer = new byte[length * _imageInfo.SectorSize]; _disk.Seek((long)(sectorAddress * _imageInfo.SectorSize), SeekOrigin.Begin); _disk.Read(buffer, 0, (int)(length * _imageInfo.SectorSize)); - return buffer; + return ErrorNumber.NoError; } } } \ No newline at end of file diff --git a/Aaru.Images/RsIde/Read.cs b/Aaru.Images/RsIde/Read.cs index a025b0312..9e4a2c096 100644 --- a/Aaru.Images/RsIde/Read.cs +++ b/Aaru.Images/RsIde/Read.cs @@ -104,18 +104,21 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSector(ulong sectorAddress) => ReadSectors(sectorAddress, 1); + public ErrorNumber ReadSector(ulong sectorAddress, out byte[] buffer) => + ReadSectors(sectorAddress, 1, out buffer); /// - public byte[] ReadSectors(ulong sectorAddress, uint length) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, out byte[] buffer) { + buffer = null; + if(sectorAddress > _imageInfo.Sectors - 1) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), "Sector address not found"); + return ErrorNumber.OutOfRange; if(sectorAddress + length > _imageInfo.Sectors) - throw new ArgumentOutOfRangeException(nameof(length), "Requested more sectors than available"); + return ErrorNumber.OutOfRange; - byte[] buffer = new byte[length * _imageInfo.SectorSize]; + buffer = new byte[length * _imageInfo.SectorSize]; Stream stream = _rsIdeImageFilter.GetDataForkStream(); @@ -123,7 +126,7 @@ namespace Aaru.DiscImages stream.Read(buffer, 0, (int)(length * _imageInfo.SectorSize)); - return buffer; + return ErrorNumber.NoError; } /// diff --git a/Aaru.Images/SaveDskF/Read.cs b/Aaru.Images/SaveDskF/Read.cs index 241d16e54..c411e09c7 100644 --- a/Aaru.Images/SaveDskF/Read.cs +++ b/Aaru.Images/SaveDskF/Read.cs @@ -141,23 +141,26 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSector(ulong sectorAddress) => ReadSectors(sectorAddress, 1); + public ErrorNumber ReadSector(ulong sectorAddress, out byte[] buffer) => + ReadSectors(sectorAddress, 1, out buffer); /// - public byte[] ReadSectors(ulong sectorAddress, uint length) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, out byte[] buffer) { + buffer = null; + if(sectorAddress > _imageInfo.Sectors - 1) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), "Sector address not found"); + return ErrorNumber.OutOfRange; if(sectorAddress + length > _imageInfo.Sectors) - throw new ArgumentOutOfRangeException(nameof(length), "Requested more sectors than available"); + return ErrorNumber.OutOfRange; - byte[] buffer = new byte[length * _imageInfo.SectorSize]; + buffer = new byte[length * _imageInfo.SectorSize]; Array.Copy(_decodedDisk, (int)sectorAddress * _imageInfo.SectorSize, buffer, 0, length * _imageInfo.SectorSize); - return buffer; + return ErrorNumber.NoError; } } } \ No newline at end of file diff --git a/Aaru.Images/SuperCardPro/Read.cs b/Aaru.Images/SuperCardPro/Read.cs index b4ebc5c71..557458f89 100644 --- a/Aaru.Images/SuperCardPro/Read.cs +++ b/Aaru.Images/SuperCardPro/Read.cs @@ -265,15 +265,20 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSector(ulong sectorAddress) => ReadSectors(sectorAddress, 1); + public ErrorNumber ReadSector(ulong sectorAddress, out byte[] buffer) => + ReadSectors(sectorAddress, 1, out buffer); /// public byte[] ReadSectorTag(ulong sectorAddress, SectorTagType tag) => throw new NotImplementedException("Flux decoding is not yet implemented."); /// - public byte[] ReadSectors(ulong sectorAddress, uint length) => - throw new NotImplementedException("Flux decoding is not yet implemented."); + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, out byte[] buffer) + { + buffer = null; + + return ErrorNumber.NotImplemented; + } /// public byte[] ReadSectorsTag(ulong sectorAddress, uint length, SectorTagType tag) => diff --git a/Aaru.Images/T98/Read.cs b/Aaru.Images/T98/Read.cs index e5ba5ae61..aab37d3b0 100644 --- a/Aaru.Images/T98/Read.cs +++ b/Aaru.Images/T98/Read.cs @@ -77,18 +77,21 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSector(ulong sectorAddress) => ReadSectors(sectorAddress, 1); + public ErrorNumber ReadSector(ulong sectorAddress, out byte[] buffer) => + ReadSectors(sectorAddress, 1, out buffer); /// - public byte[] ReadSectors(ulong sectorAddress, uint length) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, out byte[] buffer) { + buffer = null; + if(sectorAddress > _imageInfo.Sectors - 1) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), "Sector address not found"); + return ErrorNumber.OutOfRange; if(sectorAddress + length > _imageInfo.Sectors) - throw new ArgumentOutOfRangeException(nameof(length), "Requested more sectors than available"); + return ErrorNumber.OutOfRange; - byte[] buffer = new byte[length * _imageInfo.SectorSize]; + buffer = new byte[length * _imageInfo.SectorSize]; Stream stream = _t98ImageFilter.GetDataForkStream(); @@ -96,7 +99,7 @@ namespace Aaru.DiscImages stream.Read(buffer, 0, (int)(length * _imageInfo.SectorSize)); - return buffer; + return ErrorNumber.NoError; } } } \ No newline at end of file diff --git a/Aaru.Images/TeleDisk/Read.cs b/Aaru.Images/TeleDisk/Read.cs index 26259f72c..4cffed66b 100644 --- a/Aaru.Images/TeleDisk/Read.cs +++ b/Aaru.Images/TeleDisk/Read.cs @@ -530,47 +530,68 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSector(ulong sectorAddress) + public ErrorNumber ReadSector(ulong sectorAddress, out byte[] buffer) { + buffer = null; (ushort cylinder, byte head, byte sector) = LbaToChs(sectorAddress); if(cylinder >= _sectorsData.Length) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), "Sector address not found"); + return ErrorNumber.SectorNotFound; if(head >= _sectorsData[cylinder].Length) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), "Sector address not found"); + return ErrorNumber.SectorNotFound; if(sector > _sectorsData[cylinder][head].Length) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), "Sector address not found"); + return ErrorNumber.SectorNotFound; - return _sectorsData[cylinder][head][sector]; + buffer = _sectorsData[cylinder][head][sector]; + + return ErrorNumber.NoError; } /// - public byte[] ReadSectors(ulong sectorAddress, uint length) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, out byte[] buffer) { + buffer = null; + if(sectorAddress > _imageInfo.Sectors - 1) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), "Sector address not found"); + return ErrorNumber.OutOfRange; if(sectorAddress + length > _imageInfo.Sectors) - throw new ArgumentOutOfRangeException(nameof(length), "Requested more sectors than available"); + return ErrorNumber.OutOfRange; - var buffer = new MemoryStream(); + var ms = new MemoryStream(); for(uint i = 0; i < length; i++) { - byte[] sector = ReadSector(sectorAddress + i) ?? new byte[_imageInfo.SectorSize]; - buffer.Write(sector, 0, sector.Length); + ErrorNumber errno = ReadSector(sectorAddress + i, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return errno; + + ms.Write(sector, 0, sector.Length); } - return buffer.ToArray(); + buffer = ms.ToArray(); + + return ErrorNumber.NoError; } /// - public byte[] ReadSectorLong(ulong sectorAddress) => ReadSectors(sectorAddress, 1); + public byte[] ReadSectorLong(ulong sectorAddress) + { + ErrorNumber errno = ReadSectors(sectorAddress, 1, out byte[] buffer); + + return errno == ErrorNumber.NoError ? buffer : null; + } /// - public byte[] ReadSectorsLong(ulong sectorAddress, uint length) => ReadSectors(sectorAddress, length); + public byte[] ReadSectorsLong(ulong sectorAddress, uint length) + { + ErrorNumber errno = ReadSectors(sectorAddress, 1, out byte[] buffer); + + return errno == ErrorNumber.NoError ? buffer : null; + } /// public ErrorNumber ReadMediaTag(MediaTagType tag, out byte[] buffer) diff --git a/Aaru.Images/UDIF/Read.cs b/Aaru.Images/UDIF/Read.cs index a60e8ee0e..8f8faac76 100644 --- a/Aaru.Images/UDIF/Read.cs +++ b/Aaru.Images/UDIF/Read.cs @@ -395,14 +395,15 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSector(ulong sectorAddress) + public ErrorNumber ReadSector(ulong sectorAddress, out byte[] buffer) { - if(sectorAddress > _imageInfo.Sectors - 1) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), - $"Sector address {sectorAddress} not found"); + buffer = null; - if(_sectorCache.TryGetValue(sectorAddress, out byte[] sector)) - return sector; + if(sectorAddress > _imageInfo.Sectors - 1) + return ErrorNumber.OutOfRange; + + if(_sectorCache.TryGetValue(sectorAddress, out buffer)) + return ErrorNumber.NoError; var readChunk = new BlockChunk(); bool chunkFound = false; @@ -418,16 +419,14 @@ namespace Aaru.DiscImages long relOff = ((long)sectorAddress - (long)chunkStartSector) * SECTOR_SIZE; if(relOff < 0) - throw new ArgumentOutOfRangeException(nameof(relOff), - $"Got a negative offset for sector {sectorAddress}. This should not happen."); + return ErrorNumber.InvalidArgument; if(!chunkFound) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), - $"Sector address {sectorAddress} not found"); + return ErrorNumber.SectorNotFound; if((readChunk.type & CHUNK_TYPE_COMPRESSED_MASK) == CHUNK_TYPE_COMPRESSED_MASK) { - if(!_chunkCache.TryGetValue(chunkStartSector, out byte[] buffer)) + if(!_chunkCache.TryGetValue(chunkStartSector, out byte[] data)) { byte[] cmpBuffer = new byte[readChunk.length]; _imageStream.Seek((long)(readChunk.offset + _footer.dataForkOff), SeekOrigin.Begin); @@ -450,8 +449,7 @@ namespace Aaru.DiscImages break; case CHUNK_TYPE_RLE: break; - default: - throw new ImageNotSupportedException($"Unsupported chunk type 0x{readChunk.type:X8} found"); + default: return ErrorNumber.NotImplemented; } #if DEBUG @@ -468,8 +466,8 @@ namespace Aaru.DiscImages case CHUNK_TYPE_BZIP: tmpBuffer = new byte[_buffersize]; realSize = decStream?.Read(tmpBuffer, 0, (int)_buffersize) ?? 0; - buffer = new byte[realSize]; - Array.Copy(tmpBuffer, 0, buffer, 0, realSize); + data = new byte[realSize]; + Array.Copy(tmpBuffer, 0, data, 0, realSize); if(_currentChunkCacheSize + realSize > MAX_CACHE_SIZE) { @@ -477,7 +475,7 @@ namespace Aaru.DiscImages _currentChunkCacheSize = 0; } - _chunkCache.Add(chunkStartSector, buffer); + _chunkCache.Add(chunkStartSector, data); _currentChunkCacheSize += (uint)realSize; break; @@ -497,8 +495,8 @@ namespace Aaru.DiscImages realSize++; } - buffer = new byte[realSize]; - Array.Copy(tmpBuffer, 0, buffer, 0, realSize); + data = new byte[realSize]; + Array.Copy(tmpBuffer, 0, data, 0, realSize); break; } @@ -513,64 +511,71 @@ namespace Aaru.DiscImages #endif } - sector = new byte[SECTOR_SIZE]; - Array.Copy(buffer, relOff, sector, 0, SECTOR_SIZE); + buffer = new byte[SECTOR_SIZE]; + Array.Copy(data, relOff, buffer, 0, SECTOR_SIZE); if(_sectorCache.Count >= MAX_CACHED_SECTORS) _sectorCache.Clear(); - _sectorCache.Add(sectorAddress, sector); + _sectorCache.Add(sectorAddress, buffer); - return sector; + return ErrorNumber.NoError; } switch(readChunk.type) { case CHUNK_TYPE_NOCOPY: case CHUNK_TYPE_ZERO: - sector = new byte[SECTOR_SIZE]; + buffer = new byte[SECTOR_SIZE]; if(_sectorCache.Count >= MAX_CACHED_SECTORS) _sectorCache.Clear(); - _sectorCache.Add(sectorAddress, sector); + _sectorCache.Add(sectorAddress, buffer); - return sector; + return ErrorNumber.NoError; case CHUNK_TYPE_COPY: _imageStream.Seek((long)(readChunk.offset + (ulong)relOff + _footer.dataForkOff), SeekOrigin.Begin); - sector = new byte[SECTOR_SIZE]; - _imageStream.Read(sector, 0, sector.Length); + buffer = new byte[SECTOR_SIZE]; + _imageStream.Read(buffer, 0, buffer.Length); if(_sectorCache.Count >= MAX_CACHED_SECTORS) _sectorCache.Clear(); - _sectorCache.Add(sectorAddress, sector); + _sectorCache.Add(sectorAddress, buffer); - return sector; + return ErrorNumber.NoError; } - throw new ImageNotSupportedException($"Unsupported chunk type 0x{readChunk.type:X8} found"); + return ErrorNumber.NotImplemented; } /// - public byte[] ReadSectors(ulong sectorAddress, uint length) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, out byte[] buffer) { + buffer = null; + if(sectorAddress > _imageInfo.Sectors - 1) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), - $"Sector address {sectorAddress} not found"); + return ErrorNumber.OutOfRange; if(sectorAddress + length > _imageInfo.Sectors) - throw new ArgumentOutOfRangeException(nameof(length), "Requested more sectors than available"); + return ErrorNumber.OutOfRange; var ms = new MemoryStream(); for(uint i = 0; i < length; i++) { - byte[] sector = ReadSector(sectorAddress + i); + ErrorNumber errno = ReadSector(sectorAddress + i, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return errno; + ms.Write(sector, 0, sector.Length); } - return ms.ToArray(); + buffer = ms.ToArray(); + + return ErrorNumber.NoError; } } } \ No newline at end of file diff --git a/Aaru.Images/UkvFdi/Read.cs b/Aaru.Images/UkvFdi/Read.cs index 3be451740..6de87453c 100644 --- a/Aaru.Images/UkvFdi/Read.cs +++ b/Aaru.Images/UkvFdi/Read.cs @@ -186,40 +186,51 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSector(ulong sectorAddress) + public ErrorNumber ReadSector(ulong sectorAddress, out byte[] buffer) { + buffer = null; (ushort cylinder, byte head, byte sector) = LbaToChs(sectorAddress); if(cylinder >= _sectorsData.Length) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), "Sector address not found"); + return ErrorNumber.SectorNotFound; if(head >= _sectorsData[cylinder].Length) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), "Sector address not found"); + return ErrorNumber.SectorNotFound; if(sector > _sectorsData[cylinder][head].Length) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), "Sector address not found"); + return ErrorNumber.SectorNotFound; - return _sectorsData[cylinder][head][sector - 1]; + buffer = _sectorsData[cylinder][head][sector - 1]; + + return ErrorNumber.NoError; } /// - public byte[] ReadSectors(ulong sectorAddress, uint length) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, out byte[] buffer) { + buffer = null; + if(sectorAddress > _imageInfo.Sectors - 1) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), "Sector address not found"); + return ErrorNumber.OutOfRange; if(sectorAddress + length > _imageInfo.Sectors) - throw new ArgumentOutOfRangeException(nameof(length), "Requested more sectors than available"); + return ErrorNumber.OutOfRange; - var buffer = new MemoryStream(); + var ms = new MemoryStream(); for(uint i = 0; i < length; i++) { - byte[] sector = ReadSector(sectorAddress + i); - buffer.Write(sector, 0, sector.Length); + ErrorNumber errno = ReadSector(sectorAddress + i, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return errno; + + ms.Write(sector, 0, sector.Length); } - return buffer.ToArray(); + buffer = ms.ToArray(); + + return ErrorNumber.NoError; } } } \ No newline at end of file diff --git a/Aaru.Images/VDI/Read.cs b/Aaru.Images/VDI/Read.cs index 1a2eb4c01..0ff12198a 100644 --- a/Aaru.Images/VDI/Read.cs +++ b/Aaru.Images/VDI/Read.cs @@ -194,14 +194,15 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSector(ulong sectorAddress) + public ErrorNumber ReadSector(ulong sectorAddress, out byte[] buffer) { - if(sectorAddress > _imageInfo.Sectors - 1) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), - $"Sector address {sectorAddress} not found"); + buffer = null; - if(_sectorCache.TryGetValue(sectorAddress, out byte[] sector)) - return sector; + if(sectorAddress > _imageInfo.Sectors - 1) + return ErrorNumber.OutOfRange; + + if(_sectorCache.TryGetValue(sectorAddress, out buffer)) + return ErrorNumber.NoError; ulong index = sectorAddress * _vHdr.sectorSize / _vHdr.blockSize; ulong secOff = sectorAddress * _vHdr.sectorSize % _vHdr.blockSize; @@ -209,44 +210,54 @@ namespace Aaru.DiscImages uint ibmOff = _ibm[(int)index]; if(ibmOff == VDI_EMPTY) - return new byte[_vHdr.sectorSize]; + { + buffer = new byte[_vHdr.sectorSize]; + + return ErrorNumber.NoError; + } ulong imageOff = _vHdr.offsetData + ((ulong)ibmOff * _vHdr.blockSize); byte[] cluster = new byte[_vHdr.blockSize]; _imageStream.Seek((long)imageOff, SeekOrigin.Begin); _imageStream.Read(cluster, 0, (int)_vHdr.blockSize); - sector = new byte[_vHdr.sectorSize]; - Array.Copy(cluster, (int)secOff, sector, 0, _vHdr.sectorSize); + buffer = new byte[_vHdr.sectorSize]; + Array.Copy(cluster, (int)secOff, buffer, 0, _vHdr.sectorSize); if(_sectorCache.Count > MAX_CACHED_SECTORS) _sectorCache.Clear(); - _sectorCache.Add(sectorAddress, sector); + _sectorCache.Add(sectorAddress, buffer); - return sector; + return ErrorNumber.NoError; } /// - public byte[] ReadSectors(ulong sectorAddress, uint length) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, out byte[] buffer) { + buffer = null; + if(sectorAddress > _imageInfo.Sectors - 1) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), - $"Sector address {sectorAddress} not found"); + return ErrorNumber.OutOfRange; if(sectorAddress + length > _imageInfo.Sectors) - throw new ArgumentOutOfRangeException(nameof(length), - $"Requested more sectors ({sectorAddress} + {length}) than available ({_imageInfo.Sectors})"); + return ErrorNumber.OutOfRange; var ms = new MemoryStream(); for(uint i = 0; i < length; i++) { - byte[] sector = ReadSector(sectorAddress + i); + ErrorNumber errno = ReadSector(sectorAddress + i, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return errno; + ms.Write(sector, 0, sector.Length); } - return ms.ToArray(); + buffer = ms.ToArray(); + + return ErrorNumber.NoError; } } } \ No newline at end of file diff --git a/Aaru.Images/VHD/Read.cs b/Aaru.Images/VHD/Read.cs index bf33dc923..8bf6fe94c 100644 --- a/Aaru.Images/VHD/Read.cs +++ b/Aaru.Images/VHD/Read.cs @@ -663,7 +663,7 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSector(ulong sectorAddress) + public ErrorNumber ReadSector(ulong sectorAddress, out byte[] buffer) { switch(_thisFooter.DiskType) { @@ -676,7 +676,11 @@ namespace Aaru.DiscImages uint sectorInBlock = (uint)(sectorAddress % (_thisDynamic.BlockSize / 512)); if(_blockAllocationTable[blockNumber] == 0xFFFFFFFF) - return new byte[512]; + { + buffer = new byte[512]; + + return ErrorNumber.NoError; + } byte[] bitmap = new byte[_bitmapSize * 512]; @@ -709,19 +713,19 @@ namespace Aaru.DiscImages // Sector has been written, read from child image if(!dirty) - return _parentImage.ReadSector(sectorAddress); + return _parentImage.ReadSector(sectorAddress, out buffer); /* Too noisy AaruConsole.DebugWriteLine("VirtualPC plugin", "Sector {0} is dirty", sectorAddress); */ - byte[] data = new byte[512]; - uint sectorOffset = _blockAllocationTable[blockNumber] + _bitmapSize + sectorInBlock; + buffer = new byte[512]; + uint sectorOffset = _blockAllocationTable[blockNumber] + _bitmapSize + sectorInBlock; thisStream = _thisFilter.GetDataForkStream(); thisStream.Seek(sectorOffset * 512, SeekOrigin.Begin); - thisStream.Read(data, 0, 512); + thisStream.Read(buffer, 0, 512); - return data; + return ErrorNumber.NoError; /* Too noisy AaruConsole.DebugWriteLine("VirtualPC plugin", "Sector {0} is clean", sectorAddress); @@ -730,24 +734,26 @@ namespace Aaru.DiscImages // Read sector from parent image } - default: return ReadSectors(sectorAddress, 1); + default: return ReadSectors(sectorAddress, 1, out buffer); } } /// - public byte[] ReadSectors(ulong sectorAddress, uint length) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, out byte[] buffer) { + buffer = null; + switch(_thisFooter.DiskType) { case TYPE_FIXED: { - byte[] data = new byte[512 * length]; + buffer = new byte[512 * length]; Stream thisStream = _thisFilter.GetDataForkStream(); thisStream.Seek((long)(sectorAddress * 512), SeekOrigin.Begin); - thisStream.Read(data, 0, (int)(512 * length)); + thisStream.Read(buffer, 0, (int)(512 * length)); - return data; + return ErrorNumber.NoError; } // Contrary to Microsoft's specifications that tell us to check the bitmap @@ -774,7 +780,12 @@ namespace Aaru.DiscImages // Asked to read more sectors than are remaining in block if(length > remainingInBlock) { - suffix = ReadSectors(sectorAddress + remainingInBlock, length - remainingInBlock); + ErrorNumber errno = ReadSectors(sectorAddress + remainingInBlock, length - remainingInBlock, + out suffix); + + if(errno != ErrorNumber.NoError) + return errno; + sectorsToReadHere = remainingInBlock; } else @@ -800,28 +811,36 @@ namespace Aaru.DiscImages // If we needed to read from another block, join all the data if(suffix == null) - return prefix; + { + buffer = prefix; - byte[] data = new byte[512 * length]; - Array.Copy(prefix, 0, data, 0, prefix.Length); - Array.Copy(suffix, 0, data, prefix.Length, suffix.Length); + return ErrorNumber.NoError; + } - return data; + buffer = new byte[512 * length]; + Array.Copy(prefix, 0, buffer, 0, prefix.Length); + Array.Copy(suffix, 0, buffer, prefix.Length, suffix.Length); + + return ErrorNumber.NoError; } case TYPE_DIFFERENCING: { // As on differencing images, each independent sector can be read from child or parent // image, we must read sector one by one - byte[] fullData = new byte[512 * length]; + buffer = new byte[512 * length]; for(ulong i = 0; i < length; i++) { - byte[] oneSector = ReadSector(sectorAddress + i); - Array.Copy(oneSector, 0, fullData, (int)(i * 512), 512); + ErrorNumber errno = ReadSector(sectorAddress + i, out byte[] oneSector); + + if(errno != ErrorNumber.NoError) + return errno; + + Array.Copy(oneSector, 0, buffer, (int)(i * 512), 512); } - return fullData; + return ErrorNumber.NoError; } case TYPE_DEPRECATED1: diff --git a/Aaru.Images/VHDX/Read.cs b/Aaru.Images/VHDX/Read.cs index 5df627932..b502e1961 100644 --- a/Aaru.Images/VHDX/Read.cs +++ b/Aaru.Images/VHDX/Read.cs @@ -430,14 +430,15 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSector(ulong sectorAddress) + public ErrorNumber ReadSector(ulong sectorAddress, out byte[] buffer) { - if(sectorAddress > _imageInfo.Sectors - 1) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), - $"Sector address {sectorAddress} not found"); + buffer = null; - if(_sectorCache.TryGetValue(sectorAddress, out byte[] sector)) - return sector; + if(sectorAddress > _imageInfo.Sectors - 1) + return ErrorNumber.OutOfRange; + + if(_sectorCache.TryGetValue(sectorAddress, out buffer)) + return ErrorNumber.NoError; ulong index = sectorAddress * _logicalSectorSize / _vFileParms.blockSize; ulong secOff = sectorAddress * _logicalSectorSize % _vFileParms.blockSize; @@ -452,10 +453,18 @@ namespace Aaru.DiscImages switch(blkFlags & BAT_FLAGS_MASK) { case PAYLOAD_BLOCK_NOT_PRESENT: - return _hasParent ? _parentImage.ReadSector(sectorAddress) : new byte[_logicalSectorSize]; + if(_hasParent) + return _parentImage.ReadSector(sectorAddress, out buffer); + + buffer = new byte[_logicalSectorSize]; + + return ErrorNumber.NoError; case PAYLOAD_BLOCK_UNDEFINED: case PAYLOAD_BLOCK_ZERO: - case PAYLOAD_BLOCK_UNMAPPER: return new byte[_logicalSectorSize]; + case PAYLOAD_BLOCK_UNMAPPER: + buffer = new byte[_logicalSectorSize]; + + return ErrorNumber.NoError; } bool partialBlock; @@ -464,7 +473,7 @@ namespace Aaru.DiscImages if(partialBlock && _hasParent && !CheckBitmap(sectorAddress)) - return _parentImage.ReadSector(sectorAddress); + return _parentImage.ReadSector(sectorAddress, out buffer); if(!_blockCache.TryGetValue(blkPtr & BAT_FILE_OFFSET_MASK, out byte[] block)) { @@ -478,37 +487,43 @@ namespace Aaru.DiscImages _blockCache.Add(blkPtr & BAT_FILE_OFFSET_MASK, block); } - sector = new byte[_logicalSectorSize]; - Array.Copy(block, (int)secOff, sector, 0, sector.Length); + buffer = new byte[_logicalSectorSize]; + Array.Copy(block, (int)secOff, buffer, 0, buffer.Length); if(_sectorCache.Count >= _maxSectorCache) _sectorCache.Clear(); - _sectorCache.Add(sectorAddress, sector); + _sectorCache.Add(sectorAddress, buffer); - return sector; + return ErrorNumber.NoError; } /// - public byte[] ReadSectors(ulong sectorAddress, uint length) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, out byte[] buffer) { + buffer = null; + if(sectorAddress > _imageInfo.Sectors - 1) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), - $"Sector address {sectorAddress} not found"); + return ErrorNumber.OutOfRange; if(sectorAddress + length > _imageInfo.Sectors) - throw new ArgumentOutOfRangeException(nameof(length), - $"Requested more sectors ({sectorAddress + length}) than available ({_imageInfo.Sectors})"); + return ErrorNumber.OutOfRange; var ms = new MemoryStream(); for(uint i = 0; i < length; i++) { - byte[] sector = ReadSector(sectorAddress + i); + ErrorNumber errno = ReadSector(sectorAddress + i, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return errno; + ms.Write(sector, 0, sector.Length); } - return ms.ToArray(); + buffer = ms.ToArray(); + + return ErrorNumber.NoError; } } } \ No newline at end of file diff --git a/Aaru.Images/VMware/Read.cs b/Aaru.Images/VMware/Read.cs index fca0ab4a2..c07a77df5 100644 --- a/Aaru.Images/VMware/Read.cs +++ b/Aaru.Images/VMware/Read.cs @@ -530,14 +530,15 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSector(ulong sectorAddress) + public ErrorNumber ReadSector(ulong sectorAddress, out byte[] buffer) { - if(sectorAddress > _imageInfo.Sectors - 1) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), - $"Sector address {sectorAddress} not found"); + buffer = null; - if(_sectorCache.TryGetValue(sectorAddress, out byte[] sector)) - return sector; + if(sectorAddress > _imageInfo.Sectors - 1) + return ErrorNumber.OutOfRange; + + if(_sectorCache.TryGetValue(sectorAddress, out buffer)) + return ErrorNumber.NoError; var currentExtent = new Extent(); bool extentFound = false; @@ -551,22 +552,21 @@ namespace Aaru.DiscImages } if(!extentFound) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), - $"Sector address {sectorAddress} not found"); + return ErrorNumber.SectorNotFound; Stream dataStream; switch(currentExtent.Type) { case "ZERO": - sector = new byte[SECTOR_SIZE]; + buffer = new byte[SECTOR_SIZE]; if(_sectorCache.Count >= MAX_CACHED_SECTORS) _sectorCache.Clear(); - _sectorCache.Add(sectorAddress, sector); + _sectorCache.Add(sectorAddress, buffer); - return sector; + return ErrorNumber.NoError; case "FLAT": case "VMFS": dataStream = currentExtent.Filter.GetDataForkStream(); @@ -574,15 +574,15 @@ namespace Aaru.DiscImages dataStream.Seek((long)((currentExtent.Offset + (sectorAddress - extentStartSector)) * SECTOR_SIZE), SeekOrigin.Begin); - sector = new byte[SECTOR_SIZE]; - dataStream.Read(sector, 0, sector.Length); + buffer = new byte[SECTOR_SIZE]; + dataStream.Read(buffer, 0, buffer.Length); if(_sectorCache.Count >= MAX_CACHED_SECTORS) _sectorCache.Clear(); - _sectorCache.Add(sectorAddress, sector); + _sectorCache.Add(sectorAddress, buffer); - return sector; + return ErrorNumber.NoError; } ulong index = sectorAddress / _grainSize; @@ -591,19 +591,19 @@ namespace Aaru.DiscImages uint grainOff = _gTable[index]; if(grainOff == 0 && _hasParent) - return _parentImage.ReadSector(sectorAddress); + return _parentImage.ReadSector(sectorAddress, out buffer); if(grainOff == 0 || grainOff == 1) { - sector = new byte[SECTOR_SIZE]; + buffer = new byte[SECTOR_SIZE]; if(_sectorCache.Count >= MAX_CACHED_SECTORS) _sectorCache.Clear(); - _sectorCache.Add(sectorAddress, sector); + _sectorCache.Add(sectorAddress, buffer); - return sector; + return ErrorNumber.NoError; } if(!_grainCache.TryGetValue(grainOff, out byte[] grain)) @@ -619,36 +619,43 @@ namespace Aaru.DiscImages _grainCache.Add(grainOff, grain); } - sector = new byte[SECTOR_SIZE]; - Array.Copy(grain, (int)secOff, sector, 0, SECTOR_SIZE); + buffer = new byte[SECTOR_SIZE]; + Array.Copy(grain, (int)secOff, buffer, 0, SECTOR_SIZE); if(_sectorCache.Count > MAX_CACHED_SECTORS) _sectorCache.Clear(); - _sectorCache.Add(sectorAddress, sector); + _sectorCache.Add(sectorAddress, buffer); - return sector; + return ErrorNumber.NoError; } /// - public byte[] ReadSectors(ulong sectorAddress, uint length) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, out byte[] buffer) { + buffer = null; + if(sectorAddress > _imageInfo.Sectors - 1) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), - $"Sector address {sectorAddress} not found"); + return ErrorNumber.OutOfRange; if(sectorAddress + length > _imageInfo.Sectors) - throw new ArgumentOutOfRangeException(nameof(length), "Requested more sectors than available"); + return ErrorNumber.OutOfRange; var ms = new MemoryStream(); for(uint i = 0; i < length; i++) { - byte[] sector = ReadSector(sectorAddress + i); + ErrorNumber errno = ReadSector(sectorAddress + i, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return errno; + ms.Write(sector, 0, sector.Length); } - return ms.ToArray(); + buffer = ms.ToArray(); + + return ErrorNumber.NoError; } } } \ No newline at end of file diff --git a/Aaru.Images/Virtual98/Read.cs b/Aaru.Images/Virtual98/Read.cs index 47bd168b6..fad90aedd 100644 --- a/Aaru.Images/Virtual98/Read.cs +++ b/Aaru.Images/Virtual98/Read.cs @@ -79,24 +79,25 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSector(ulong sectorAddress) => ReadSectors(sectorAddress, 1); + public ErrorNumber ReadSector(ulong sectorAddress, out byte[] buffer) => ReadSectors(sectorAddress, 1, out buffer); /// - public byte[] ReadSectors(ulong sectorAddress, uint length) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, out byte[] buffer) { + buffer = null; if(sectorAddress > _imageInfo.Sectors - 1) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), "Sector address not found"); + return ErrorNumber.OutOfRange; if(sectorAddress + length > _imageInfo.Sectors) - throw new ArgumentOutOfRangeException(nameof(length), "Requested more sectors than available"); + return ErrorNumber.OutOfRange; - byte[] buffer = new byte[length * _imageInfo.SectorSize]; + buffer = new byte[length * _imageInfo.SectorSize]; Stream stream = _nhdImageFilter.GetDataForkStream(); // V98 are lazy allocated if((long)(0xDC + (sectorAddress * _imageInfo.SectorSize)) >= stream.Length) - return buffer; + return ErrorNumber.NoError; stream.Seek((long)(0xDC + (sectorAddress * _imageInfo.SectorSize)), SeekOrigin.Begin); @@ -107,7 +108,7 @@ namespace Aaru.DiscImages stream.Read(buffer, 0, toRead); - return buffer; + return ErrorNumber.NoError; } } } \ No newline at end of file diff --git a/Aaru.Images/WCDiskImage/Read.cs b/Aaru.Images/WCDiskImage/Read.cs index 11db370d2..af9ada64e 100644 --- a/Aaru.Images/WCDiskImage/Read.cs +++ b/Aaru.Images/WCDiskImage/Read.cs @@ -163,7 +163,7 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSector(ulong sectorAddress) + public ErrorNumber ReadSector(ulong sectorAddress, out byte[] buffer) { int sectorNumber = (int)(sectorAddress % _imageInfo.SectorsPerTrack) + 1; int trackNumber = (int)(sectorAddress / _imageInfo.SectorsPerTrack); @@ -177,27 +177,49 @@ namespace Aaru.DiscImages /* if we have sector data, return that */ if(_sectorCache.ContainsKey((cylinderNumber, headNumber, sectorNumber))) - return _sectorCache[(cylinderNumber, headNumber, sectorNumber)]; + { + buffer = _sectorCache[(cylinderNumber, headNumber, sectorNumber)]; + + return ErrorNumber.NoError; + } /* otherwise, return an empty sector */ - return new byte[512]; + buffer = new byte[512]; + + return ErrorNumber.NoError; } - return _sectorCache[(cylinderNumber, headNumber, sectorNumber)]; + buffer = _sectorCache[(cylinderNumber, headNumber, sectorNumber)]; + + return ErrorNumber.NoError; } /// - public byte[] ReadSectors(ulong sectorAddress, uint length) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, out byte[] buffer) { - byte[] result = new byte[length * _imageInfo.SectorSize]; + buffer = null; + + if(sectorAddress > _imageInfo.Sectors - 1) + return ErrorNumber.OutOfRange; if(sectorAddress + length > _imageInfo.Sectors) - throw new ArgumentOutOfRangeException(nameof(length), "Requested more sectors than available"); + return ErrorNumber.OutOfRange; - for(int i = 0; i < length; i++) - ReadSector(sectorAddress + (ulong)i).CopyTo(result, i * _imageInfo.SectorSize); + var ms = new MemoryStream(); - return result; + for(uint i = 0; i < length; i++) + { + ErrorNumber errno = ReadSector(sectorAddress + i, out byte[] sector); + + if(errno != ErrorNumber.NoError) + return errno; + + ms.Write(sector, 0, sector.Length); + } + + buffer = ms.ToArray(); + + return ErrorNumber.NoError; } /// Read a whole track and cache it diff --git a/Aaru.Images/ZZZRawImage/Read.cs b/Aaru.Images/ZZZRawImage/Read.cs index 2968808b0..3b316b557 100644 --- a/Aaru.Images/ZZZRawImage/Read.cs +++ b/Aaru.Images/ZZZRawImage/Read.cs @@ -1196,19 +1196,22 @@ namespace Aaru.DiscImages } /// - public byte[] ReadSector(ulong sectorAddress) => ReadSectors(sectorAddress, 1); + public ErrorNumber ReadSector(ulong sectorAddress, out byte[] buffer) => + ReadSectors(sectorAddress, 1, out buffer); /// - public byte[] ReadSectors(ulong sectorAddress, uint length) + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, out byte[] buffer) { + buffer = null; + if(_differentTrackZeroSize) throw new NotImplementedException("Not yet implemented"); if(sectorAddress > _imageInfo.Sectors - 1) - throw new ArgumentOutOfRangeException(nameof(sectorAddress), "Sector address not found"); + return ErrorNumber.OutOfRange; if(sectorAddress + length > _imageInfo.Sectors) - throw new ArgumentOutOfRangeException(nameof(length), "Requested more sectors than available"); + return ErrorNumber.OutOfRange; Stream stream = _rawImageFilter.GetDataForkStream(); @@ -1226,7 +1229,7 @@ namespace Aaru.DiscImages if(_hasSubchannel) sectorSkip += 96; - byte[] buffer = new byte[sectorSize * length]; + buffer = new byte[sectorSize * length]; var br = new BinaryReader(stream); br.BaseStream.Seek((long)(sectorAddress * (sectorOffset + sectorSize + sectorSkip)), SeekOrigin.Begin); @@ -1259,7 +1262,7 @@ namespace Aaru.DiscImages Array.Copy(sector, 0, buffer, i * sectorSize, sectorSize); } - return buffer; + return ErrorNumber.NoError; } /// @@ -1337,7 +1340,9 @@ namespace Aaru.DiscImages if(track != 1) throw new ArgumentOutOfRangeException(nameof(track), "Only a single track is supported"); - return ReadSector(sectorAddress); + ErrorNumber errno = ReadSector(sectorAddress, out byte[] buffer); + + return errno == ErrorNumber.NoError ? buffer : null; } /// @@ -1349,7 +1354,9 @@ namespace Aaru.DiscImages if(track != 1) throw new ArgumentOutOfRangeException(nameof(track), "Only a single track is supported"); - return ReadSectors(sectorAddress, length); + ErrorNumber errno = ReadSectors(sectorAddress, length, out byte[] buffer); + + return errno == ErrorNumber.NoError ? buffer : null; } /// diff --git a/Aaru.Partitions/Acorn.cs b/Aaru.Partitions/Acorn.cs index a068b2f12..1f47bb816 100644 --- a/Aaru.Partitions/Acorn.cs +++ b/Aaru.Partitions/Acorn.cs @@ -35,6 +35,7 @@ using System.Collections.Generic; using System.Runtime.InteropServices; using System.Text; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Aaru.Helpers; using Marshal = Aaru.Helpers.Marshal; @@ -57,7 +58,7 @@ namespace Aaru.Partitions /// public string Name => "Acorn FileCore partitions"; /// - public Guid Id => new Guid("A7C8FEBE-8D00-4933-B9F3-42184C8BA808"); + public Guid Id => new("A7C8FEBE-8D00-4933-B9F3-42184C8BA808"); /// public string Author => "Natalia Portillo"; @@ -77,9 +78,10 @@ namespace Aaru.Partitions else sbSector = ADFS_SB_POS / imagePlugin.Info.SectorSize; - byte[] sector = imagePlugin.ReadSector(sbSector); + ErrorNumber errno = imagePlugin.ReadSector(sbSector, out byte[] sector); - if(sector.Length < 512) + if(errno != ErrorNumber.NoError || + sector.Length < 512) return false; AcornBootBlock bootBlock = Marshal.ByteArrayToStructureLittleEndian(sector); @@ -96,7 +98,10 @@ namespace Aaru.Partitions if((ulong)mapSector >= imagePlugin.Info.Sectors) return false; - byte[] map = imagePlugin.ReadSector((ulong)mapSector); + errno = imagePlugin.ReadSector((ulong)mapSector, out byte[] map); + + if(errno != ErrorNumber.NoError) + return false; ulong counter = 0; diff --git a/Aaru.Partitions/AppleMap.cs b/Aaru.Partitions/AppleMap.cs index be2114a9b..096b02b24 100644 --- a/Aaru.Partitions/AppleMap.cs +++ b/Aaru.Partitions/AppleMap.cs @@ -36,6 +36,7 @@ using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; using System.Text; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Aaru.Console; using Aaru.Helpers; @@ -62,7 +63,7 @@ namespace Aaru.Partitions /// public string Name => "Apple Partition Map"; /// - public Guid Id => new Guid("36405F8D-4F1A-07F5-209C-223D735D6D22"); + public Guid Id => new("36405F8D-4F1A-07F5-209C-223D735D6D22"); /// public string Author => "Natalia Portillo"; @@ -82,7 +83,10 @@ namespace Aaru.Partitions if(sectorOffset + 2 >= imagePlugin.Info.Sectors) return false; - byte[] ddmSector = imagePlugin.ReadSector(sectorOffset); + ErrorNumber errno = imagePlugin.ReadSector(sectorOffset, out byte[] ddmSector); + + if(errno != ErrorNumber.NoError) + return false; ushort maxDrivers = 61; @@ -150,7 +154,10 @@ namespace Aaru.Partitions } } - byte[] partSector = imagePlugin.ReadSector(1 + sectorOffset); + errno = imagePlugin.ReadSector(1 + sectorOffset, out byte[] partSector); + + if(errno != ErrorNumber.NoError) + return false; AppleOldDevicePartitionMap oldMap = Marshal.ByteArrayToStructureBigEndian(partSector); @@ -257,7 +264,11 @@ namespace Aaru.Partitions return partitions.Count > 0; } - byte[] entries = imagePlugin.ReadSectors(sectorOffset, sectorsToRead); + errno = imagePlugin.ReadSectors(sectorOffset, sectorsToRead, out byte[] entries); + + if(errno != ErrorNumber.NoError) + return false; + AaruConsole.DebugWriteLine("AppleMap Plugin", "entry_size = {0}", entrySize); AaruConsole.DebugWriteLine("AppleMap Plugin", "entry_count = {0}", entryCount); AaruConsole.DebugWriteLine("AppleMap Plugin", "skip_ddm = {0}", skipDdm); diff --git a/Aaru.Partitions/Apricot.cs b/Aaru.Partitions/Apricot.cs index a054b929d..0035cd722 100644 --- a/Aaru.Partitions/Apricot.cs +++ b/Aaru.Partitions/Apricot.cs @@ -34,6 +34,7 @@ using System; using System.Collections.Generic; using System.Runtime.InteropServices; using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Aaru.Console; using Aaru.Helpers; @@ -86,7 +87,7 @@ namespace Aaru.Partitions /// public string Name => "ACT Apricot partitions"; /// - public Guid Id => new Guid("8CBF5864-7B5A-47A0-8CEB-199C74FA22DE"); + public Guid Id => new("8CBF5864-7B5A-47A0-8CEB-199C74FA22DE"); /// public string Author => "Natalia Portillo"; @@ -99,9 +100,10 @@ namespace Aaru.Partitions if(sectorOffset != 0) return false; - byte[] sector = imagePlugin.ReadSector(0); + ErrorNumber errno = imagePlugin.ReadSector(0, out byte[] sector); - if(sector.Length < 512) + if(errno != ErrorNumber.NoError || + sector.Length < 512) return false; Label label = Marshal.ByteArrayToStructureLittleEndian