From 068ee76983625a22755e7022df1d20248a46f2ac Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Mon, 9 Jan 2023 22:15:37 -0800 Subject: [PATCH] Add generic data reading --- BurnOutSharp.Wrappers/CFB.cs | 114 ++++++++++++++++++++++++++++++++--- 1 file changed, 106 insertions(+), 8 deletions(-) diff --git a/BurnOutSharp.Wrappers/CFB.cs b/BurnOutSharp.Wrappers/CFB.cs index 67c67817..e18bf4a1 100644 --- a/BurnOutSharp.Wrappers/CFB.cs +++ b/BurnOutSharp.Wrappers/CFB.cs @@ -166,16 +166,16 @@ namespace BurnOutSharp.Wrappers /// /// Initial FAT sector /// Ordered list of sector numbers, null on error - public List GetFATSectorChain(uint startingSector) + public List GetFATSectorChain(Models.CFB.SectorNumber startingSector) { // If we have an invalid sector - if (startingSector < 0 || startingSector >= FATSectorNumbers.Length) + if (startingSector < 0 || (long)startingSector >= FATSectorNumbers.Length) return null; // Setup the returned list - var sectors = new List { (Models.CFB.SectorNumber)startingSector }; + var sectors = new List { startingSector }; - var lastSector = (Models.CFB.SectorNumber)startingSector; + var lastSector = startingSector; while (true) { // Get the next sector from the lookup table @@ -193,21 +193,55 @@ namespace BurnOutSharp.Wrappers return sectors; } + /// + /// Get the data for the FAT sector chain starting at a given starting sector + /// + /// Initial FAT sector + /// Ordered list of sector numbers, null on error + public byte[] GetFATSectorChainData(Models.CFB.SectorNumber startingSector) + { + // Get the sector chain first + var sectorChain = GetFATSectorChain(startingSector); + if (sectorChain == null) + return null; + + // Sequentially read the sectors + var data = new List(); + for (int i = 0; i < sectorChain.Count; i++) + { + // Try to get the sector data offset + int sectorDataOffset = (int)ToFileOffset(sectorChain[i]); + if (sectorDataOffset < 0 || sectorDataOffset >= GetEndOfFile()) + return null; + + // Try to read the sector data + int sectorDataLength = (int)Math.Pow(2, SectorShift); + var sectorData = ReadFromDataSource(sectorDataOffset, sectorDataLength); + if (sectorData == null) + return null; + + // Add the sector data to the output + data.AddRange(sectorData); + } + + return data.ToArray(); + } + /// /// Get the ordered Mini FAT sector chain for a given starting sector /// /// Initial Mini FAT sector /// Ordered list of sector numbers, null on error - public List GetMiniFATSectorChain(uint startingSector) + public List GetMiniFATSectorChain(Models.CFB.SectorNumber startingSector) { // If we have an invalid sector - if (startingSector < 0 || startingSector >= MiniFATSectorNumbers.Length) + if (startingSector < 0 || (long)startingSector >= MiniFATSectorNumbers.Length) return null; // Setup the returned list - var sectors = new List { (Models.CFB.SectorNumber)startingSector }; + var sectors = new List { startingSector }; - var lastSector = (Models.CFB.SectorNumber)startingSector; + var lastSector = startingSector; while (true) { // Get the next sector from the lookup table @@ -225,6 +259,70 @@ namespace BurnOutSharp.Wrappers return sectors; } + /// + /// Get the data for the Mini FAT sector chain starting at a given starting sector + /// + /// Initial Mini FAT sector + /// Ordered list of sector numbers, null on error + public byte[] GetMiniFATSectorChainData(Models.CFB.SectorNumber startingSector) + { + // Get the sector chain first + var sectorChain = GetMiniFATSectorChain(startingSector); + if (sectorChain == null) + return null; + + // Sequentially read the sectors + var data = new List(); + for (int i = 0; i < sectorChain.Count; i++) + { + // Try to get the sector data offset + int sectorDataOffset = (int)ToMiniFileOffset(sectorChain[i]); + if (sectorDataOffset < 0 || sectorDataOffset >= GetEndOfFile()) + return null; + + // Try to read the sector data + int sectorDataLength = (int)Math.Pow(2, MiniSectorShift); + var sectorData = ReadFromDataSource(sectorDataOffset, sectorDataLength); + if (sectorData == null) + return null; + + // Add the sector data to the output + data.AddRange(sectorData); + } + + return data.ToArray(); + } + + /// + /// Convert a FAT sector value to a byte offset + /// + /// Sector to convert + /// File offset in bytes, -1 on error + public long ToFileOffset(Models.CFB.SectorNumber sector) + { + // If we have an invalid sector number + if (sector > Models.CFB.SectorNumber.MAXREGSECT) + return -1; + + // Convert based on the sector shift value + return (long)((long)(sector + 1) * Math.Pow(2, SectorShift)); + } + + /// + /// Convert a Mini FAT sector value to a byte offset + /// + /// Sector to convert + /// File offset in bytes, -1 on error + public long ToMiniFileOffset(Models.CFB.SectorNumber sector) + { + // If we have an invalid sector number + if (sector > Models.CFB.SectorNumber.MAXREGSECT) + return -1; + + // Convert based on the sector shift value + return (long)((long)(sector + 1) * Math.Pow(2, MiniSectorShift)); + } + #endregion #region Printing