/// <summary> /// Gets the EOF value for the specified FAT type. /// </summary> /// <param name="aFATType">The FAT type.</param> /// <returns>The EOF value.</returns> public static UInt32 GetFATEntryEOFValue(FATTypeEnum aFATType) { if (aFATType == FATTypeEnum.FAT12) { return 0x0FF8; } else if (aFATType == FATTypeEnum.FAT16) { return 0xFFF8; } else { return 0x0FFFFFF8; } }
/// <summary> /// Initializes a new FAT file system from the specified partition. /// </summary> /// <param name="aPartition">The partition on which the file system resides.</param> /// <remarks> /// You should check IsValid after creating a new FAT file system to check a valid FAT /// file system has been detected. /// </remarks> public FATFileSystem(Partition aPartition) : base(aPartition) { //Create an array to store the BPB data. byte[] BPBData = thePartition.NewBlockArray(1); //Load the BIOS Parameter Block - the first sector of the partition. thePartition.ReadBlock(0UL, 1U, BPBData); //Check the top two bytes for the signature if (BPBData[510] != 0x55 || BPBData[511] != 0xAA) { //If they are wrong, this is not a valid FAT file system. return; } //The signature is the only thing we can check to determine if this is FAT // so we must now assume this is a valid FAT file system. isValid = true; //Load or calculate the various bits of data required to use a FAT file system. BytesPerSector = ByteConverter.ToUInt16(BPBData, 11); SectorsPerCluster = BPBData[13]; BytesPerCluster = BytesPerSector * SectorsPerCluster; ReservedSectorCount = ByteConverter.ToUInt16(BPBData, 14); NumberOfFATs = BPBData[16]; RootEntryCount = ByteConverter.ToUInt16(BPBData, 17); TotalSectorCount = ByteConverter.ToUInt16(BPBData, 19); if (TotalSectorCount == 0) { TotalSectorCount = ByteConverter.ToUInt32(BPBData, 32); } //Valid for FAT12/16 //Invalid for FAT32, SectorCount always 0 in this field. FATSectorCount = ByteConverter.ToUInt16(BPBData, 22); if (FATSectorCount == 0) { //FAT32 has a different, larger field for sector count FATSectorCount = ByteConverter.ToUInt32(BPBData, 36); } DataSectorCount = TotalSectorCount - (ReservedSectorCount + (NumberOfFATs * FATSectorCount)); // Computation rounds down. ClusterCount = DataSectorCount / SectorsPerCluster; // Determine the FAT type. //This is the official and proper way to determine FAT type - don't alter it. // - If you want to implement some hack, add a new FAT file system class / // implementation and add it to the appropriate partition initialisation // methods // Comparisons are purposefully < and not <= // FAT16 starts at 4085, FAT32 starts at 65525 if (ClusterCount < 4085) { FATType = FATTypeEnum.FAT12; } else if (ClusterCount < 65525) { FATType = FATTypeEnum.FAT16; } else { FATType = FATTypeEnum.FAT32; } if (FATType == FATTypeEnum.FAT32) { RootCluster = ByteConverter.ToUInt32(BPBData, 44); } else { RootSector = ReservedSectorCount + (NumberOfFATs * FATSectorCount); RootSectorCount = (RootEntryCount * 32 + (BytesPerSector - 1)) / BytesPerSector; } DataSector = ReservedSectorCount + (NumberOfFATs * FATSectorCount) + RootSectorCount; }