Add all but directory sectors

This commit is contained in:
Matt Nadareski
2023-01-09 14:32:40 -08:00
parent b7704dbe57
commit 008629b61f
3 changed files with 117 additions and 7 deletions

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using BurnOutSharp.Models.CFB;
using BurnOutSharp.Utilities;
using static BurnOutSharp.Models.CFB.Constants;
@@ -68,9 +69,96 @@ namespace BurnOutSharp.Builders
#endregion
// TODO: Implement FAT sector parsing
// TODO: Implement Mini FAT sector parsing
// TODO: Implement DIFAT sector parsing
#region FAT Sectors
// Create a FAT sector table
var fatSectors = new List<SectorNumber>();
// Loop through and add the FAT sectors
for (int i = 0; i < fileHeader.NumberOfFATSectors; i++)
{
// Try to get the FAT sector offset
long offset = (long)(fileHeader.DIFAT[i] * Math.Pow(2, fileHeader.SectorShift));
if (offset < 0 || offset >= data.Length)
return null;
// Seek to the offset
data.Seek(offset, SeekOrigin.Begin);
// Try to parse the sectors
var sectorNumbers = ParseSector(data, fileHeader.SectorShift);
if (sectorNumbers == null)
return null;
// Add the sector shifts
fatSectors.AddRange(sectorNumbers);
}
// Assign the FAT sectors table
binary.FATSectors = fatSectors.ToArray();
#endregion
#region Mini FAT Sectors
// Get the offset of the first mini FAT sector
long firstMiniFatOffset = (long)(fileHeader.FirstMiniFATSectorLocation * Math.Pow(2, fileHeader.SectorShift));
if (firstMiniFatOffset < 0 || firstMiniFatOffset >= data.Length)
return null;
// Seek to the first mini FAT sector
data.Seek(firstMiniFatOffset, SeekOrigin.Begin);
// Create a mini FAT sector table
var miniFatSectors = new List<SectorNumber>();
// Loop through and add the mini FAT sectors
for (int i = 0; i < fileHeader.NumberOfMiniFATSectors; i++)
{
// Try to parse the sectors
var sectorNumbers = ParseSector(data, fileHeader.SectorShift);
if (sectorNumbers == null)
return null;
// Add the sector shifts
miniFatSectors.AddRange(sectorNumbers);
}
// Assign the mini FAT sectors table
binary.MiniFATSectors = miniFatSectors.ToArray();
#endregion
#region DIFAT Sectors
// Get the offset of the first DIFAT sector
long firstDifatOffset = (long)(fileHeader.FirstDIFATSectorLocation * Math.Pow(2, fileHeader.SectorShift));
if (firstDifatOffset < 0 || firstDifatOffset >= data.Length)
return null;
// Seek to the first DIFAT sector
data.Seek(firstDifatOffset, SeekOrigin.Begin);
// Create a DIFAT sector table
var difatSectors = new List<SectorNumber>();
// Loop through and add the DIFAT sectors
for (int i = 0; i < fileHeader.NumberOfMiniFATSectors; i++)
{
// Try to parse the sectors
var sectorNumbers = ParseSector(data, fileHeader.SectorShift);
if (sectorNumbers == null)
return null;
// Add the sector shifts
difatSectors.AddRange(sectorNumbers);
}
// Assign the DIFAT sectors table
binary.DIFATSectors = difatSectors.ToArray();
#endregion
// TODO: Implement directory sector parsing
return binary;
@@ -86,8 +174,8 @@ namespace BurnOutSharp.Builders
// TODO: Use marshalling here instead of building
FileHeader header = new FileHeader();
header.Signature = data.ReadBytes(8);
if (header.Signature != SignatureBytes)
header.Signature = data.ReadUInt64();
if (header.Signature != SignatureUInt64)
return null;
header.CLSID = data.ReadGuid();
@@ -133,6 +221,26 @@ namespace BurnOutSharp.Builders
return header;
}
/// <summary>
/// Parse a Stream into a sector full of sector numbers
/// </summary>
/// <param name="data">Stream to parse</param>
/// <param name="sectorShift">Sector shift from the header</param>
/// <returns>Filled sector full of sector numbers on success, null on error</returns>
private static SectorNumber[] ParseSector(Stream data, ushort sectorShift)
{
// TODO: Use marshalling here instead of building
int sectorCount = (int)(Math.Pow(2, sectorShift) / sizeof(uint));
SectorNumber[] sectorNumbers = new SectorNumber[sectorCount];
for (int i = 0; i < sectorNumbers.Length; i++)
{
sectorNumbers[i] = (SectorNumber)data.ReadUInt32();
}
return sectorNumbers;
}
#endregion
}
}

View File

@@ -3,5 +3,7 @@ namespace BurnOutSharp.Models.CFB
public static class Constants
{
public static readonly byte[] SignatureBytes = new byte[] { 0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1 };
public const ulong SignatureUInt64 = 0xE11AB1A1E011CFD0;
}
}

View File

@@ -9,7 +9,7 @@ namespace BurnOutSharp.Models.CFB
/// IOdentification signature for the compound file structure, and MUST be
/// set to the value 0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1.
/// </summary>
public byte[] Signature;
public ulong Signature;
/// <summary>
/// Reserved and unused class ID that MUST be set to all zeroes (CLSID_NULL)