Read Xbox FAT root directory.

This commit is contained in:
2019-04-07 13:31:27 +01:00
parent 6d43c83712
commit c25d37b3c2
4 changed files with 97 additions and 11 deletions

View File

@@ -40,11 +40,20 @@ namespace DiscImageChef.Filesystems.FATX
const uint FATX_CIGAM = 0x46415458;
const byte UNUSED_DIRENTRY = 0x00;
const byte DELETED_DIRENTRY = 0xE5;
const byte FINISHED_DIRENTRY = 0xFF;
const byte MAX_FILENAME = 42;
const int MAX_XFAT16_CLUSTERS = 65525;
const int FAT_START = 4096;
const uint FATX32_ID = 0xFFFFFFF8;
const ushort FATX16_ID = 0xFFF8;
const uint FAT32_MASK = 0x0FFFFFFF;
const uint FAT32_END_MASK = 0xFFFFFF8;
const uint FAT32_FORMATTED = 0xFFFFFF6;
const uint FAT32_BAD = 0xFFFFFF7;
const ushort FAT16_END_MASK = 0xFFF8;
const ushort FAT16_FORMATTED = 0xFFF6;
const ushort FAT16_BAD = 0xFFF7;
const ushort FAT_RESERVED = 1;
[Flags]
enum Attributes : byte

View File

@@ -42,6 +42,7 @@ namespace DiscImageChef.Filesystems.FATX
{
public partial class XboxFatPlugin : IReadOnlyFilesystem
{
uint bytesPerCluster;
ushort[] fat16;
uint[] fat32;
ulong fatStartSector;
@@ -50,6 +51,7 @@ namespace DiscImageChef.Filesystems.FATX
bool littleEndian;
bool mounted;
Partition partition;
Dictionary<string, DirectoryEntry> rootDirectory;
uint sectorsPerCluster;
FileSystemInfo stat;

View File

@@ -31,6 +31,7 @@
// ****************************************************************************/
using System;
using System.Collections.Generic;
using DiscImageChef.CommonTypes.Structs;
namespace DiscImageChef.Filesystems.FATX
@@ -67,5 +68,35 @@ namespace DiscImageChef.Filesystems.FATX
throw new NotImplementedException();
}
uint[] GetClusters(uint startCluster)
{
if(startCluster == 0) return null;
if(fat16 is null)
{
if(startCluster >= fat32.Length) return null;
}
else if(startCluster >= fat16.Length) return null;
List<uint> clusters = new List<uint>();
uint nextCluster = startCluster;
if(fat16 is null)
while((nextCluster & FAT32_MASK) > 0 && (nextCluster & FAT32_MASK) <= FAT32_BAD)
{
clusters.Add(nextCluster);
nextCluster = fat32[nextCluster];
}
else
while(nextCluster > 0 && nextCluster <= FAT16_BAD)
{
clusters.Add(nextCluster);
nextCluster = fat16[nextCluster];
}
return clusters.ToArray();
}
}
}

View File

@@ -159,11 +159,55 @@ namespace DiscImageChef.Filesystems.FATX
this.partition = partition;
this.imagePlugin = imagePlugin;
firstClusterSector = fatStartSector + fatSize;
bytesPerCluster = sectorsPerCluster * imagePlugin.Info.SectorSize;
DicConsole.DebugWriteLine("Xbox FAT plugin", "sectorsPerCluster = {0}", sectorsPerCluster);
DicConsole.DebugWriteLine("Xbox FAT plugin", "bytesPerCluster = {0}", bytesPerCluster);
DicConsole.DebugWriteLine("Xbox FAT plugin", "firstClusterSector = {0}", firstClusterSector);
throw new NotImplementedException();
uint[] rootDirectoryClusters = GetClusters(superblock.rootDirectoryCluster);
if(rootDirectoryClusters is null) return Errno.InvalidArgument;
byte[] rootDirectoryBuffer = new byte[bytesPerCluster * rootDirectoryClusters.Length];
DicConsole.DebugWriteLine("Xbox FAT plugin", "Reading root directory");
for(int i = 0; i < rootDirectoryClusters.Length; i++)
{
buffer =
imagePlugin.ReadSectors(firstClusterSector + (rootDirectoryClusters[i] - 1) * sectorsPerCluster,
sectorsPerCluster);
Array.Copy(buffer, 0, rootDirectoryBuffer, i * bytesPerCluster, bytesPerCluster);
}
rootDirectory = new Dictionary<string, DirectoryEntry>();
int pos = 0;
while(pos < rootDirectoryBuffer.Length)
{
DirectoryEntry entry = littleEndian
? Marshal
.ByteArrayToStructureLittleEndian<DirectoryEntry
>(rootDirectoryBuffer, pos, Marshal.SizeOf<DirectoryEntry>())
: Marshal.ByteArrayToStructureBigEndian<DirectoryEntry>(rootDirectoryBuffer,
pos,
Marshal
.SizeOf<
DirectoryEntry
>());
pos += Marshal.SizeOf<DirectoryEntry>();
if(entry.filenameSize == UNUSED_DIRENTRY || entry.filenameSize == FINISHED_DIRENTRY) break;
if(entry.filenameSize == DELETED_DIRENTRY || entry.filenameSize > MAX_FILENAME) continue;
string filename = Encoding.GetString(entry.filename, 0, entry.filenameSize);
rootDirectory.Add(filename, entry);
}
return Errno.NoError;
}
public Errno Unmount()