Skip to content

Commit

Permalink
Added support for earlier (v1) DVT3 HDD format
Browse files Browse the repository at this point in the history
  • Loading branch information
aerosoul94 committed Jul 30, 2023
1 parent c22ca3e commit f8b6842
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 7 deletions.
17 changes: 15 additions & 2 deletions FATX/DriveReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,19 @@ public void Initialize()
return;
}

Seek(0x80004);
if (ReadUInt32() == 0x58544146)
{
Console.WriteLine("Mounting Xbox DVT3 HDD (v1)..");

AddPartition("Partition1", 0x80000, 0x1312D6000, true); // DATA
AddPartition("Partition2", 0x131356000, 0x1f400000, true); // SHELL
AddPartition("Partition3", 0x150756000, 0x2ee00000, true); // CACHE
AddPartition("Partition4", 0x17F556000, 0x2ee00000, true); // CACHE
AddPartition("Partition5", 0x1AE356000, 0x2ee00000, true); // CACHE
return;
}

// Check for XBOX 360 partitions.
Seek(0);
ByteOrder = ByteOrder.Big;
Expand Down Expand Up @@ -148,9 +161,9 @@ public void Initialize()
}
}

public void AddPartition(string name, long offset, long length)
public void AddPartition(string name, long offset, long length, bool legacy = false)
{
Volume partition = new Volume(this, name, offset, length);
Volume partition = new Volume(this, name, offset, length, legacy);
_partitions.Add(partition);
}

Expand Down
69 changes: 64 additions & 5 deletions FATX/FileSystem/Volume.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,39 @@ public class Volume
private uint _fatByteOffset;
private uint _fileAreaByteOffset;

private bool _usesLegacyFormat;
private uint _jump;
private ushort _bytesPerSector;
private ushort _reservedSectors;
private ushort _sectorsPerTrack;
private ushort _heads;
private uint _hiddenSectors;
private uint _largeSectors;
private uint _largeSectorsPerFat;

private List<DirectoryEntry> _root = new List<DirectoryEntry>();
private uint[] _fileAllocationTable;
private long _fileAreaLength;
private Platform _platform;

public Volume(DriveReader reader, string name, long offset, long length)
/// <summary>
/// Creates a new FATX volume.
/// </summary>
/// <param name="reader">The stream that contains the FATX file system.</param>
/// <param name="name">The name of this volume.</param>
/// <param name="offset">The offset within the <paramref name="reader"/> this partition exists at.</param>
/// <param name="length">The length in bytes of this partition.</param>
/// <param name="legacy">
/// Set this to true if this is the legacy FATX file system.
/// It appears to only be used in older DVT3 xbox systems with kernel 3633 or earlier.
/// </param>
public Volume(DriveReader reader, string name, long offset, long length, bool legacy = false)
{
this._reader = reader;
this._partitionName = name;
this._partitionLength = length;
this._partitionOffset = offset;
this._usesLegacyFormat = legacy;

this._platform = (reader.ByteOrder == ByteOrder.Big) ?
Platform.X360 : Platform.Xbox;
Expand Down Expand Up @@ -112,7 +134,7 @@ public void Mount()
Mounted = false;

// Read and verify volume metadata.
ReadVolumeMetadata();
ReadBootSector();
CalculateOffsets();
ReadFileAllocationTable();

Expand All @@ -125,21 +147,58 @@ public void Mount()
/// <summary>
/// Read and verifies the FATX header.
/// </summary>
private void ReadVolumeMetadata()
private void ReadBootSector()
{
_reader.Seek(_partitionOffset);
Console.WriteLine("Attempting to load FATX volume at {0:X16}", _reader.Position);

if (!_usesLegacyFormat)
{
ReadVolumeMetadata();
}
else
{
ReadLegacyVolumeMetadata();
}
}

private void ReadVolumeMetadata()
{
_signature = _reader.ReadUInt32();
_serialNumber = _reader.ReadUInt32();
_sectorsPerCluster = _reader.ReadUInt32();
_rootDirFirstCluster = _reader.ReadUInt32();

if (_signature != VolumeSignature)
{
throw new FormatException(
String.Format("Invalid FATX Signature for {0}: {1:X8}", _partitionName, _signature.ToString("X8")));
throw new FormatException($"Invalid FATX Signature for {_partitionName}: {_signature:X8}");
}
}

private void ReadLegacyVolumeMetadata()
{
// Read _BOOT_SECTOR
_jump = _reader.ReadUInt32(); // EB FE
_signature = _reader.ReadUInt32(); // FATX
_serialNumber = _reader.ReadUInt32(); // 05C29C00

if (_signature != VolumeSignature)
{
throw new FormatException($"Invalid FATX Signature for {_partitionName}: {_signature:X8}");
}

// Read BIOS_PARAMETER_BLOCK
// These fields are currently not being used by this reader. With some testing, we'll see if these fields
// are truly necessary.
_bytesPerSector = _reader.ReadUInt16(); // 0200
_sectorsPerCluster = _reader.ReadByte(); // 20
_reservedSectors = _reader.ReadUInt16(); // 08
_sectorsPerTrack = _reader.ReadUInt16(); // 3F00
_heads = _reader.ReadUInt16(); // FF00
_hiddenSectors = _reader.ReadUInt32(); // 00000400
_largeSectors = _reader.ReadUInt32(); // 009896B0
_largeSectorsPerFat = _reader.ReadUInt32(); // 00000990
_rootDirFirstCluster = _reader.ReadUInt32(); // 00000001
}

/// <summary>
Expand Down

0 comments on commit f8b6842

Please sign in to comment.