コード例 #1
0
        /// <summary>
        ///     Scan FAT o miniFAT for free sectors to reuse.
        /// </summary>
        /// <param name="sType">Type of sector to look for</param>
        /// <returns>A stack of available sectors or minisectors already allocated</returns>
        internal Queue<Sector> FindFreeSectors(SectorType sType)
        {
            var freeList = new Queue<Sector>();

            if (sType == SectorType.Normal)
            {
                var fatChain = GetSectorChain(-1, SectorType.FAT);
                var fatStream = new StreamView(fatChain, GetSectorSize(), _header.FATSectorsNumber*GetSectorSize(),
                    SourceStream);

                var idx = 0;

                while (idx < _sectors.Count)
                {
                    var id = fatStream.ReadInt32();

                    if (id == Sector.FreeSector)
                    {
                        if (_sectors[idx] == null)
                        {
                            var sector = new Sector(GetSectorSize(), SourceStream) {Id = idx};
                            _sectors[idx] = sector;
                        }

                        freeList.Enqueue(_sectors[idx]);
                    }

                    idx++;
                }
            }
            else
            {
                var miniFAT
                    = GetSectorChain(_header.FirstMiniFATSectorId, SectorType.Normal);

                var miniFATView
                    = new StreamView(miniFAT, GetSectorSize(), _header.MiniFATSectorsNumber*Sector.MinisectorSize,
                        SourceStream);

                var miniStream
                    = GetSectorChain(RootEntry.StartSector, SectorType.Normal);

                var miniStreamView
                    = new StreamView(miniStream, GetSectorSize(), RootStorage.Size, SourceStream);

                long ptr = 0;

                var nMinisectors = (int) (miniStreamView.Length/Sector.MinisectorSize);

                while (ptr < nMinisectors)
                {
                    //AssureLength(miniStreamView, (int)miniFATView.Length);

                    var id = miniFATView.ReadInt32();
                    ptr += 4;

                    if (id != Sector.FreeSector) continue;
                    var miniSector = new Sector(Sector.MinisectorSize, SourceStream)
                    {
                        Id = (int) ((ptr - 4)/4),
                        Type = SectorType.Mini
                    };

                    miniStreamView.Seek(miniSector.Id*Sector.MinisectorSize, SeekOrigin.Begin);
                    miniStreamView.Read(miniSector.GetData(), 0, Sector.MinisectorSize);

                    freeList.Enqueue(miniSector);
                }
            }

            return freeList;
        }
コード例 #2
0
        /// <summary>
        ///     Get a standard sector chain
        /// </summary>
        /// <param name="secId">First SecID of the required chain</param>
        /// <returns>A list of sectors</returns>
        /// <exception cref="CFCorruptedFileException">Raised when the file is corrupt</exception>
        private List<Sector> GetNormalSectorChain(int secId)
        {
            var result = new List<Sector>();

            var nextSecId = secId;

            var fatSectors = GetFatSectorChain();

            var fatStream
                = new StreamView(fatSectors, GetSectorSize(), fatSectors.Count*GetSectorSize(), SourceStream);

            while (true)
            {
                if (nextSecId == Sector.Endofchain) break;

                if (nextSecId >= _sectors.Count)
                    throw new CFCorruptedFileException(
                        string.Format(
                            "Next Sector ID reference an out of range sector. NextID : {0} while sector count {1}",
                            nextSecId, _sectors.Count));

                var sector = _sectors[nextSecId];
                if (sector == null)
                {
                    sector = new Sector(GetSectorSize(), SourceStream) {Id = nextSecId, Type = SectorType.Normal};
                    _sectors[nextSecId] = sector;
                }

                result.Add(sector);

                fatStream.Seek(nextSecId*4, SeekOrigin.Begin);
                var next = fatStream.ReadInt32();

                if (next != nextSecId)
                    nextSecId = next;
                else
                    throw new CFCorruptedFileException("Cyclic sector chain found. File is corrupted");
            }

            return result;
        }