diff --git a/Aaru.Filesystems/LisaFS/Dir.cs b/Aaru.Filesystems/LisaFS/Dir.cs index 5682dc061..5f9b04519 100644 --- a/Aaru.Filesystems/LisaFS/Dir.cs +++ b/Aaru.Filesystems/LisaFS/Dir.cs @@ -127,7 +127,7 @@ public sealed partial class LisaFS // If root catalog is not pointed in MDDF (unchecked) maybe it's always following S-Records File? for(ulong i = 0; i < _device.Info.Sectors; i++) { - errno = _device.ReadSectorTag(i, false, SectorTagType.AppleSonyTag, out byte[] tag); + errno = ReadLisaSectorTag(i, out byte[] tag); if(errno != ErrorNumber.NoError) continue; @@ -135,7 +135,7 @@ public sealed partial class LisaFS if(catTag.FileId != FILEID_CATALOG || catTag.RelPage != 0) continue; - errno = _device.ReadSectors(i, false, 4, out firstCatalogBlock, out _); + errno = ReadLisaSectors(i, 4, out firstCatalogBlock); if(errno != ErrorNumber.NoError) return errno; @@ -150,10 +150,7 @@ public sealed partial class LisaFS // Traverse double-linked list until first catalog block while(prevCatalogPointer != 0xFFFFFFFF) { - errno = _device.ReadSectorTag(prevCatalogPointer + _mddf.mddf_block + _volumePrefix, - false, - SectorTagType.AppleSonyTag, - out byte[] tag); + errno = ReadLisaSectorTag(prevCatalogPointer + _mddf.mddf_block + _volumePrefix, out byte[] tag); if(errno != ErrorNumber.NoError) return errno; @@ -161,11 +158,7 @@ public sealed partial class LisaFS if(prevTag.FileId != FILEID_CATALOG) return ErrorNumber.InvalidArgument; - errno = _device.ReadSectors(prevCatalogPointer + _mddf.mddf_block + _volumePrefix, - false, - 4, - out firstCatalogBlock, - out _); + errno = ReadLisaSectors(prevCatalogPointer + _mddf.mddf_block + _volumePrefix, 4, out firstCatalogBlock); if(errno != ErrorNumber.NoError) return errno; @@ -179,10 +172,7 @@ public sealed partial class LisaFS // Traverse double-linked list to read full catalog while(nextCatalogPointer != 0xFFFFFFFF) { - errno = _device.ReadSectorTag(nextCatalogPointer + _mddf.mddf_block + _volumePrefix, - false, - SectorTagType.AppleSonyTag, - out byte[] tag); + errno = ReadLisaSectorTag(nextCatalogPointer + _mddf.mddf_block + _volumePrefix, out byte[] tag); if(errno != ErrorNumber.NoError) return errno; @@ -190,11 +180,9 @@ public sealed partial class LisaFS if(nextTag.FileId != FILEID_CATALOG) return ErrorNumber.InvalidArgument; - errno = _device.ReadSectors(nextCatalogPointer + _mddf.mddf_block + _volumePrefix, - false, - 4, - out byte[] nextCatalogBlock, - out _); + errno = ReadLisaSectors(nextCatalogPointer + _mddf.mddf_block + _volumePrefix, + 4, + out byte[] nextCatalogBlock); if(errno != ErrorNumber.NoError) return errno; @@ -401,4 +389,4 @@ public sealed partial class LisaFS } #endregion -} \ No newline at end of file +} diff --git a/Aaru.Filesystems/LisaFS/Extent.cs b/Aaru.Filesystems/LisaFS/Extent.cs index 08a2063b8..a07f01c03 100644 --- a/Aaru.Filesystems/LisaFS/Extent.cs +++ b/Aaru.Filesystems/LisaFS/Extent.cs @@ -57,11 +57,16 @@ public sealed partial class LisaFS ulong ptr = _srecords[fileId].extent_ptr; - // An invalid pointer denotes file does not exist - if(ptr is 0xFFFFFFFF or 0x00000000) return ErrorNumber.NoSuchFile; + var searchExtentByTag = false; // Pointers are relative to MDDF - ptr += _mddf.mddf_block + _volumePrefix; + if(ptr is not 0xFFFFFFFF and not 0x00000000) ptr += _mddf.mddf_block + _volumePrefix; + else + { + if(_srecords[fileId].filesize == 0) return ErrorNumber.NoSuchFile; + + searchExtentByTag = true; + } LisaTag.PriamTag extTag; byte[] tag; @@ -69,19 +74,19 @@ public sealed partial class LisaFS // This happens on some disks. // This is a filesystem corruption that makes LisaOS crash on scavenge. // This code just allow to ignore that corruption by searching the Extents File using sector tags - if(ptr >= _device.Info.Sectors) + if(searchExtentByTag || ptr >= _device.Info.Sectors) { var found = false; for(ulong i = 0; i < _device.Info.Sectors; i++) { - errno = _device.ReadSectorTag(i, false, SectorTagType.AppleSonyTag, out tag); + errno = ReadLisaSectorTag(i, out tag); if(errno != ErrorNumber.NoError) continue; DecodeTag(tag, out extTag); - if(extTag.FileId != fileId * -1) continue; + if(extTag.FileId != fileId * -1 || extTag.RelPage != 0) continue; ptr = i; found = true; @@ -93,17 +98,36 @@ public sealed partial class LisaFS } // Checks that the sector tag indicates its the Extents File we are searching for - errno = _device.ReadSectorTag(ptr, false, SectorTagType.AppleSonyTag, out tag); + errno = ReadLisaSectorTag(ptr, out tag); if(errno != ErrorNumber.NoError) return errno; DecodeTag(tag, out extTag); - if(extTag.FileId != (short)(-1 * fileId)) return ErrorNumber.NoSuchFile; + if(extTag.FileId != (short)(-1 * fileId) || extTag.RelPage != 0) + { + var found = false; - errno = _mddf.fsversion == LISA_V1 - ? _device.ReadSectors(ptr, false, 2, out byte[] sector, out _) - : _device.ReadSector(ptr, false, out sector, out _); + for(ulong i = 0; i < _device.Info.Sectors; i++) + { + errno = ReadLisaSectorTag(i, out tag); + + if(errno != ErrorNumber.NoError) continue; + + DecodeTag(tag, out extTag); + + if(extTag.FileId != fileId * -1 || extTag.RelPage != 0) continue; + + ptr = i; + found = true; + + break; + } + + if(!found) return ErrorNumber.NoSuchFile; + } + + errno = _mddf.fsversion == LISA_V1 ? ReadLisaSectors(ptr, 2, out byte[] sector) : ReadLisaSector(ptr, out sector); if(errno != ErrorNumber.NoError) return errno; @@ -306,11 +330,8 @@ public sealed partial class LisaFS if(!_mounted) return ErrorNumber.AccessDenied; // Searches the S-Records place using MDDF pointers - ErrorNumber errno = _device.ReadSectors(_mddf.srec_ptr + _mddf.mddf_block + _volumePrefix, - false, - _mddf.srec_len, - out byte[] sectors, - out _); + ErrorNumber errno = + ReadLisaSectors(_mddf.srec_ptr + _mddf.mddf_block + _volumePrefix, _mddf.srec_len, out byte[] sectors); if(errno != ErrorNumber.NoError) return errno; @@ -330,4 +351,4 @@ public sealed partial class LisaFS return ErrorNumber.NoError; } -} \ No newline at end of file +} diff --git a/Aaru.Filesystems/LisaFS/File.cs b/Aaru.Filesystems/LisaFS/File.cs index e877ecc70..012e86421 100644 --- a/Aaru.Filesystems/LisaFS/File.cs +++ b/Aaru.Filesystems/LisaFS/File.cs @@ -117,11 +117,7 @@ public sealed partial class LisaFS { if(!tags) { - errno = _device.ReadSectors(_mddf.mddf_block + _volumePrefix + _mddf.srec_ptr, - false, - _mddf.srec_len, - out buf, - out _); + errno = ReadLisaSectors(_mddf.mddf_block + _volumePrefix + _mddf.srec_ptr, _mddf.srec_len, out buf); if(errno != ErrorNumber.NoError) return errno; @@ -130,11 +126,7 @@ public sealed partial class LisaFS return ErrorNumber.NoError; } - errno = _device.ReadSectorsTag(_mddf.mddf_block + _volumePrefix + _mddf.srec_ptr, - false, - _mddf.srec_len, - SectorTagType.AppleSonyTag, - out buf); + errno = ReadLisaSectorsTag(_mddf.mddf_block + _volumePrefix + _mddf.srec_ptr, _mddf.srec_len, out buf); return errno != ErrorNumber.NoError ? errno : ErrorNumber.NoError; } @@ -144,7 +136,7 @@ public sealed partial class LisaFS // Should be enough to check 100 sectors? for(ulong i = 0; i < 100; i++) { - errno = _device.ReadSectorTag(i, false, SectorTagType.AppleSonyTag, out byte[] tag); + errno = ReadLisaSectorTag(i, out byte[] tag); if(errno != ErrorNumber.NoError) continue; @@ -160,7 +152,7 @@ public sealed partial class LisaFS // Should be enough to check 100 sectors? for(ulong i = 0; i < 100; i++) { - errno = _device.ReadSectorTag(i, false, SectorTagType.AppleSonyTag, out byte[] tag); + errno = ReadLisaSectorTag(i, out byte[] tag); if(errno != ErrorNumber.NoError) continue; @@ -168,9 +160,7 @@ public sealed partial class LisaFS if(sysTag.FileId != fileId) continue; - errno = !tags - ? _device.ReadSector(i, false, out byte[] sector, out _) - : _device.ReadSectorTag(i, false, SectorTagType.AppleSonyTag, out sector); + errno = !tags ? ReadLisaSector(i, out byte[] sector) : ReadLisaSectorTag(i, out sector); if(errno != ErrorNumber.NoError) continue; @@ -306,20 +296,16 @@ public sealed partial class LisaFS for(var i = 0; i < file.extents.Length; i++) { ErrorNumber errno = !tags - ? _device.ReadSectors((ulong)file.extents[i].start + - _mddf.mddf_block + - _volumePrefix, - false, - (uint)file.extents[i].length, - out byte[] sector, - out _) - : _device.ReadSectorsTag((ulong)file.extents[i].start + - _mddf.mddf_block + - _volumePrefix, - false, - (uint)file.extents[i].length, - SectorTagType.AppleSonyTag, - out sector); + ? ReadLisaSectors((ulong)file.extents[i].start + + _mddf.mddf_block + + _volumePrefix, + (uint)file.extents[i].length, + out byte[] sector) + : ReadLisaSectorsTag((ulong)file.extents[i].start + + _mddf.mddf_block + + _volumePrefix, + (uint)file.extents[i].length, + out sector); if(errno != ErrorNumber.NoError) return errno; @@ -537,4 +523,4 @@ public sealed partial class LisaFS } #endregion -} \ No newline at end of file +} diff --git a/Aaru.Filesystems/LisaFS/LisaFS.cs b/Aaru.Filesystems/LisaFS/LisaFS.cs index 1c11456c9..4913db4d6 100644 --- a/Aaru.Filesystems/LisaFS/LisaFS.cs +++ b/Aaru.Filesystems/LisaFS/LisaFS.cs @@ -30,6 +30,7 @@ using System; using System.Collections.Generic; using System.Text; using Aaru.CommonTypes.AaruMetadata; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; namespace Aaru.Filesystems; @@ -48,6 +49,7 @@ public sealed partial class LisaFS : IReadOnlyFilesystem MDDF _mddf; bool _mounted; SRecord[] _srecords; + Dictionary _twiggyBadBlockMap; ulong _volumePrefix; static Dictionary GetDefaultOptions() => new() @@ -106,4 +108,4 @@ public sealed partial class LisaFS : IReadOnlyFilesystem Dictionary _directoryDtcCache; #endregion Caches -} \ No newline at end of file +} diff --git a/Aaru.Filesystems/LisaFS/Super.cs b/Aaru.Filesystems/LisaFS/Super.cs index 047748f81..a38635693 100644 --- a/Aaru.Filesystems/LisaFS/Super.cs +++ b/Aaru.Filesystems/LisaFS/Super.cs @@ -230,6 +230,8 @@ public sealed partial class LisaFS if(_debug) _printedExtents = []; + InitializeTwiggyBadBlockMap(); + // Read the S-Records file ErrorNumber error = ReadSRecords(); @@ -356,6 +358,7 @@ public sealed partial class LisaFS _fileSizeCache = null; _printedExtents = null; _mddf = new MDDF(); + _twiggyBadBlockMap = null; _volumePrefix = 0; _devTagSize = 0; _srecords = null; @@ -398,4 +401,4 @@ public sealed partial class LisaFS } #endregion -} \ No newline at end of file +}