Example #1
0
        public FatDirectoryEntry CreateSub(Fat fat)
        {
            var chain = new ClusterChain(fat, false);

            chain.SetChainLength(1);

            var entry = FatDirectoryEntry.Create(true);

            entry.SetStartCluster(chain.GetStartCluster());

            var dir =
                new ClusterChainDirectory(chain, false);

            /* add "." entry */

            var dot = FatDirectoryEntry.Create(true);

            dot.SetShortName(ShortName.Dot);
            dot.SetStartCluster(dir.GetStorageCluster());
            CopyDateTimeFields(entry, dot);
            dir.AddEntry(dot);

            /* add ".." entry */

            var dotDot = FatDirectoryEntry.Create(true);

            dotDot.SetShortName(ShortName.DotDot);
            dotDot.SetStartCluster(GetStorageCluster());
            CopyDateTimeFields(entry, dotDot);
            dir.AddEntry(dotDot);

            dir.Flush();

            return(entry);
        }
Example #2
0
        public static ClusterChainDirectory ReadRoot(ClusterChain chain)
        {
            var result = new ClusterChainDirectory(chain, true);

            result.Read();
            return(result);
        }
Example #3
0
        /// <summary>
        /// According to the FAT file system specification, leading and trailing
        /// spaces in the name are ignored by this method.
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        /// <exception cref="IOException"></exception>
        public IFsDirectoryEntry AddDirectory(string name)
        {
            CheckWritable();
            CheckUniqueName(name);

            name = name.Trim();
            var sn   = MakeShortName(name, true);
            var real = Dir.CreateSub(fat);

            real.SetShortName(sn);
            var e = new FatLfnDirectoryEntry(this, real, name);

            try {
                Dir.AddEntries(e.CompactForm());
            }
            catch (IOException ex) {
                var cc = new ClusterChain(fat, real.GetStartCluster(), false);
                cc.SetChainLength(0);
                Dir.RemoveEntry(real);
                throw ex;
            }

            shortNameIndex.Add(sn, e);
            longNameIndex.Add(name.ToLowerInvariant(), e);

            GetDirectory(real);

            Flush();
            return(e);
        }
Example #4
0
        /// <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());
        }
Example #5
0
        private static ClusterChainDirectory Read(FatDirectoryEntry entry, Fat fat)
        {
            if (!entry.IsDirectory())
            {
                throw
                    new ArgumentException(entry + " is no directory");
            }

            var chain = new ClusterChain(
                fat, entry.GetStartCluster(),
                entry.IsReadonlyFlag());

            var result =
                new ClusterChainDirectory(chain, false);

            result.Read();
            return(result);
        }
Example #6
0
        internal static FatFile Get(Fat fat, FatDirectoryEntry entry)
        {
            if (entry.IsDirectory())
            {
                throw new ArgumentException(entry + " is a directory");
            }

            var cc = new ClusterChain(
                fat, entry.GetStartCluster(), entry.IsReadonlyFlag());

            if (entry.GetLength() > cc.GetLengthOnDisk())
            {
                throw new IOException(
                          "entry is larger than associated cluster chain");
            }

            return(new FatFile(entry, cc));
        }
Example #7
0
        /// <summary>
        /// Remove the entry with the given name from this directory.
        /// </summary>
        /// <param name="name">the name of the entry to remove</param>
        /// <exception cref="IOException">IOException on error removing the entry</exception>
        /// <exception cref="InvalidOperationException">InvalidOperationException on an attempt to remove the dot entries</exception>
        public void Remove(string name)
        {
            CheckWritable();

            if (!(GetEntry(name) is FatLfnDirectoryEntry entry))
            {
                return;
            }

            UnlinkEntry(entry);

            var cc = new ClusterChain(
                fat, entry.RealEntry.GetStartCluster(), false);

            cc.SetChainLength(0);

            FreeUniqueName(name);
            UpdateLfn();
        }
Example #8
0
        public static ClusterChainDirectory CreateRoot(Fat fat)
        {
            if (fat.GetFatType() != FatType.BaseFat32)
            {
                throw new ArgumentException(
                          "only FAT32 stores root directory in a cluster chain");
            }

            var bs = (Fat32BootSector)fat.GetBootSector();
            var cc = new ClusterChain(fat, false);

            cc.SetChainLength(1);

            bs.SetRootDirFirstCluster(cc.GetStartCluster());

            var result =
                new ClusterChainDirectory(cc, true);

            result.Flush();
            return(result);
        }
Example #9
0
 private FatFile(FatDirectoryEntry myEntry, ClusterChain chain) : base(myEntry.IsReadOnly())
 {
     entry      = myEntry;
     this.chain = chain;
 }
Example #10
0
 internal ClusterChainDirectory(ClusterChain chain, bool isRoot)
     : base((int)(chain.GetLengthOnDisk() / FatDirectoryEntry.SIZE), chain.IsReadOnly(), isRoot)
 {
     this.Chain = chain;
 }