From 020b640465b01617b74f7f91ba90569434257d6f Mon Sep 17 00:00:00 2001 From: Jeremy Powell Date: Thu, 5 Dec 2024 23:00:46 +1300 Subject: [PATCH] Handle range lock sector --- OpenMcdf/Fat.cs | 13 +++++++++++++ OpenMcdf/FatEnumerator.cs | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/OpenMcdf/Fat.cs b/OpenMcdf/Fat.cs index 1450920..9b392b8 100644 --- a/OpenMcdf/Fat.cs +++ b/OpenMcdf/Fat.cs @@ -10,7 +10,11 @@ namespace OpenMcdf; /// internal sealed class Fat : ContextBase, IEnumerable, IDisposable { + const uint RangeLockSectorOffset = 0x7FFFFF00; + const uint RangeLockSectorId = RangeLockSectorOffset / (uint)(1 << Header.SectorShiftV4); + private readonly FatSectorEnumerator fatSectorEnumerator; + private readonly Func isFree; private readonly byte[] cachedSectorBuffer; Sector cachedSector = Sector.EndOfChain; private bool isDirty; @@ -20,6 +24,13 @@ public Fat(RootContextSite rootContextSite) { fatSectorEnumerator = new(rootContextSite); cachedSectorBuffer = new byte[Context.SectorSize]; + + if (Context.Version == Version.V3) + isFree = value => value == SectorType.Free; + else if (Context.Version == Version.V4) + isFree = value => value == SectorType.Free && value != RangeLockSectorId; + else + throw new NotSupportedException($"Unsupported major version: {Context.Version}."); } public void Dispose() @@ -29,6 +40,8 @@ public void Dispose() fatSectorEnumerator.Dispose(); } + public bool IsFree(uint key) => isFree(key); + public uint this[uint key] { get diff --git a/OpenMcdf/FatEnumerator.cs b/OpenMcdf/FatEnumerator.cs index cdc429f..10e29e4 100644 --- a/OpenMcdf/FatEnumerator.cs +++ b/OpenMcdf/FatEnumerator.cs @@ -77,7 +77,7 @@ public bool MoveNextFreeEntry() { while (MoveNext()) { - if (value == SectorType.Free) + if (fat.IsFree(value)) return true; }