internal static FatLfnDirectoryEntry Extract( FatLfnDirectory dir, int offset, int len) { var realEntry = dir.Dir.GetEntry(offset + len - 1); string fileName; if (len == 1) { /* this is just an old plain 8.3 entry */ fileName = realEntry.GetShortName().AsSimpleString(); } else { /* stored in reverse order */ var name = new StringBuilder(13 * (len - 1)); for (var i = len - 2; i >= 0; i--) { var entry = dir.Dir.GetEntry(i + offset); name.Append(entry.GetLfnPart()); } fileName = name.ToString().Trim(); } return(new FatLfnDirectoryEntry(dir, realEntry, fileName)); }
internal FatLfnDirectoryEntry(FatLfnDirectory parent, FatDirectoryEntry realEntry, string fileName) : base(parent.IsReadOnly()) { this.parent = parent; this.RealEntry = realEntry; this.fileName = fileName; }
internal FatLfnDirectoryEntry(string name, ShortName sn, FatLfnDirectory parent, bool directory) : base(false) { this.parent = parent; fileName = name; var now = (long)(DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds; RealEntry = FatDirectoryEntry.Create(directory); RealEntry.SetShortName(sn); RealEntry.SetCreated(now); RealEntry.SetLastAccessed(now); }
internal FatLfnDirectory GetDirectory(FatDirectoryEntry entry) { entryToDirectory.TryGetValue(entry, out var result); if (result == null) { var storage = Read(entry, fat); result = new FatLfnDirectory(storage, fat, IsReadOnly()); entryToDirectory.Add(entry, result); } return(result); }
/// <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()); }
/// <summary> /// Moves this entry to a new directory under the specified name. /// </summary> /// <param name="target">the direcrory where this entry should be moved to</param> /// <param name="newName">the new name under which this entry will be accessible /// in the target directory</param> /// <exception cref="IOException">IOException on error moving this entry</exception> /// <exception cref="ReadOnlyException">ReadOnlyException if this directory is read-only</exception> public void MoveTo(FatLfnDirectory target, string newName) { CheckWritable(); if (!target.IsFreeName(newName)) { throw new IOException( "the name \"" + newName + "\" is already in use"); } parent.UnlinkEntry(this); parent = target; fileName = newName; parent.LinkEntry(this); }
/// <summary> /// Initializes the boot sector and file system for the device. The file /// system created by this method will always be in read-write mode. /// </summary> /// <returns>the file system that was created</returns> /// <exception cref="System.IO.IOException">IOException on write error</exception> public FatFileSystem Format() { var sectorSize = device.GetSectorSize(); var totalSectors = (int)(device.GetSize() / sectorSize); FsInfoSector fsi; BootSector bs; if (sectorsPerCluster == 0) { throw new Exception(); } if (fatType == FatType.BaseFat32) { bs = new Fat32BootSector(device); InitBootSector(bs); var f32Bs = (Fat32BootSector)bs; f32Bs.SetFsInfoSectorNr(1); f32Bs.SetSectorsPerFat(SectorsPerFat(0, totalSectors)); var rnd = new Random(); f32Bs.SetFileSystemId(rnd.Next()); f32Bs.SetVolumeLabel(label); /* create FS info sector */ fsi = FsInfoSector.Create(f32Bs); } else { bs = new Fat16BootSector(device); InitBootSector(bs); var f16Bs = (Fat16BootSector)bs; var rootDirEntries = RootDirectorySize( device.GetSectorSize(), totalSectors); f16Bs.SetRootDirEntryCount(rootDirEntries); f16Bs.SetSectorsPerFat(SectorsPerFat(rootDirEntries, totalSectors)); if (label != null) { f16Bs.SetVolumeLabel(label); } fsi = null; } // bs.write(); if (fatType == FatType.BaseFat32) { var f32Bs = (Fat32BootSector)bs; /* possibly writes the boot sector copy */ f32Bs.WriteCopy(device); } var fat = Fat.Create(bs, 0); AbstractDirectory rootDirStore; if (fatType == FatType.BaseFat32) { rootDirStore = ClusterChainDirectory.CreateRoot(fat); fsi.SetFreeClusterCount(fat.GetFreeClusterCount()); fsi.SetLastAllocatedCluster(fat.GetLastAllocatedCluster()); fsi.Write(); } else { rootDirStore = Fat16RootDirectory.Create((Fat16BootSector)bs); } var rootDir = new FatLfnDirectory(rootDirStore, fat, false); rootDir.Flush(); for (var i = 0; i < bs.GetNrFats(); i++) { fat.WriteCopy(FatUtils.GetFatOffset(bs, i)); } bs.Write(); var fs = FatFileSystem.Read(device, false); if (label != null) { fs.SetVolumeLabel(label); } fs.Flush(); return(fs); }