diff --git a/DiscImageChef.Filesystems/FAT/Consts.cs b/DiscImageChef.Filesystems/FAT/Consts.cs index 905f5d4d3..342055519 100644 --- a/DiscImageChef.Filesystems/FAT/Consts.cs +++ b/DiscImageChef.Filesystems/FAT/Consts.cs @@ -67,6 +67,16 @@ namespace DiscImageChef.Filesystems.FAT /// FASTFAT.SYS indicator that basename is lowercase /// const byte FASTFAT_LOWERCASE_BASENAME = 0x08; + 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 FAT12_END_MASK = 0xFF8; + const ushort FAT12_FORMATTED = 0xFF6; + const ushort FAT12_BAD = 0xFF7; readonly (string hash, string name)[] knownBootHashes = { diff --git a/DiscImageChef.Filesystems/FAT/File.cs b/DiscImageChef.Filesystems/FAT/File.cs index c130d5eff..d653cd159 100644 --- a/DiscImageChef.Filesystems/FAT/File.cs +++ b/DiscImageChef.Filesystems/FAT/File.cs @@ -31,6 +31,7 @@ // ****************************************************************************/ using System; +using System.Collections.Generic; using DiscImageChef.CommonTypes.Structs; namespace DiscImageChef.Filesystems.FAT @@ -67,5 +68,57 @@ namespace DiscImageChef.Filesystems.FAT throw new NotImplementedException(); } + + uint[] GetClusters(uint startCluster) + { + if(startCluster == 0) return null; + + if(startCluster >= XmlFsType.Clusters) return null; + + List clusters = new List(); + + uint nextCluster = startCluster; + + if(fat12) return null; + + ulong nextSector = nextCluster / fatEntriesPerSector + fatFirstSector; + int nextEntry = (int)(nextCluster % fatEntriesPerSector); + + ulong currentSector = nextSector; + byte[] fatData = image.ReadSector(currentSector); + + if(fat32) + while((nextCluster & FAT32_MASK) > 0 && (nextCluster & FAT32_MASK) <= FAT32_BAD) + { + clusters.Add(nextCluster); + + if(currentSector != nextSector) + { + fatData = image.ReadSector(nextSector); + currentSector = nextSector; + } + + nextCluster = BitConverter.ToUInt32(fatData, nextEntry * 4); + nextSector = nextCluster / fatEntriesPerSector + fatFirstSector; + nextEntry = (int)(nextCluster % fatEntriesPerSector); + } + else if(fat16) + while(nextCluster > 0 && nextCluster <= FAT16_BAD) + { + clusters.Add(nextCluster); + + if(currentSector != nextSector) + { + fatData = image.ReadSector(nextSector); + currentSector = nextSector; + } + + nextCluster = BitConverter.ToUInt16(fatData, nextEntry * 2); + nextSector = nextCluster / fatEntriesPerSector + fatFirstSector; + nextEntry = (int)(nextCluster % fatEntriesPerSector); + } + + return clusters.ToArray(); + } } } \ No newline at end of file