private Fat(BootSector bs, long offset) { this.bs = bs; fatType = bs.GetFatType(); if (bs.GetSectorsPerFat() > int.MaxValue) { throw new ArgumentException("FAT too large"); } if (bs.GetSectorsPerFat() <= 0) { throw new IOException( "boot sector says there are " + bs.GetSectorsPerFat() + " sectors per FAT"); } if (bs.GetBytesPerSector() <= 0) { throw new IOException( "boot sector says there are " + bs.GetBytesPerSector() + " bytes per sector"); } sectorCount = (int)bs.GetSectorsPerFat(); sectorSize = bs.GetBytesPerSector(); device = bs.GetDevice(); this.offset = offset; lastAllocatedCluster = FIRST_CLUSTER; if (bs.GetDataClusterCount() > int.MaxValue) { throw new IOException("too many data clusters"); } if (bs.GetDataClusterCount() == 0) { throw new IOException("no data clusters"); } lastClusterIndex = (int)bs.GetDataClusterCount() + FIRST_CLUSTER; entries = new long[(int)((sectorCount * sectorSize) / fatType.GetEntrySize())]; if (lastClusterIndex > entries.Length) { throw new IOException( "file system has " + lastClusterIndex + "clusters but only " + entries.Length + " FAT entries"); } }
/// <summary> /// Constructor for FatFileSystem in specified readOnly mode /// </summary> /// <param name="device">the <see cref="IBlockDevice"/> holding the file system</param> /// <param name="readOnly"></param> /// <param name="ignoreFatDifferences"></param> /// <exception cref="IOException">IOException on read error</exception> private FatFileSystem(IBlockDevice device, bool readOnly, bool ignoreFatDifferences) : base(readOnly) { bs = BootSector.Read(device); if (bs.GetNrFats() <= 0) { throw new IOException( "boot sector says there are no FATs"); } filesOffset = FatUtils.GetFilesOffset(bs); fatType = bs.GetFatType(); fat = Fat.Read(bs, 0); if (!ignoreFatDifferences) { for (var i = 1; i < bs.GetNrFats(); i++) { var tmpFat = Fat.Read(bs, i); if (!fat.Equals(tmpFat)) { throw new IOException("FAT " + i + " differs from FAT 0"); } } } if (fatType == FatType.BaseFat32) { var f32Bs = (Fat32BootSector)bs; var rootDirFile = new ClusterChain(fat, f32Bs.GetRootDirFirstCluster(), IsReadOnly()); rootDirStore = ClusterChainDirectory.ReadRoot(rootDirFile); fsiSector = FsInfoSector.Read(f32Bs); if (fsiSector.GetFreeClusterCount() != fat.GetFreeClusterCount()) { throw new IOException("free cluster count mismatch - fat: " + fat.GetFreeClusterCount() + " - fsinfo: " + fsiSector.GetFreeClusterCount()); } } else { rootDirStore = Fat16RootDirectory.Read((Fat16BootSector)bs, readOnly); fsiSector = null; } rootDir = new FatLfnDirectory(rootDirStore, fat, IsReadOnly()); }
private int DefaultSectorsPerCluster(FatType fatType) { var size = device.GetSize(); var sectorSize = device.GetSectorSize(); if (fatType == FatType.BaseFat12) { return(SectorsPerCluster12(size, sectorSize)); } if (fatType == FatType.BaseFat16) { return(SectorsPerCluster16()); } if (fatType == FatType.BaseFat32) { return(SectorsPerCluster32()); } throw new Exception(); }
/// <summary> /// Sets the type of FAT that will be created by this /// <see cref="SuperFloppyFormatter"/>. /// </summary> /// <param name="fatType">the desired <see cref="FatType"/></param> /// <returns>this <see cref="SuperFloppyFormatter"/></returns> /// <exception cref="System.IO.IOException">IOException on error setting the fatType</exception> /// <exception cref="InvalidOperationException">InvalidOperationException if fatType does not support the /// size of the device</exception> public SuperFloppyFormatter SetFatType(FatType fatType) { if (fatType == null) { throw new NullReferenceException(); } if (fatType == FatType.BaseFat12 || fatType == FatType.BaseFat16) { reservedSectors = 1; } else if (fatType == FatType.BaseFat32) { reservedSectors = 32; } sectorsPerCluster = DefaultSectorsPerCluster(fatType); this.fatType = fatType; return(this); }