Пример #1
0
        public bool TryOpenFile(string filename, out StreamView stream)
        {
            if (!EntryMap.TryGetValue(filename, out var entry))
            {
                stream = null;
                return(false);
            }

            stream = new StreamView(Stream, entry.DataPosition, entry.Length);
            return(true);
        }
Пример #2
0
        private VirtualDirectory ConvertCvmToVirtualDirectory(VirtualFile cvmFile)
        {
            using (var stream = cvmFile.Open())
            {
                var streamView       = new StreamView(stream, 0x1800, stream.Length - 0x1800);
                var cvmIsoFilesystem = new CDReader(streamView, false);

                var directory = cvmIsoFilesystem.ToVirtualDirectory();
                directory.Name = Path.GetFileNameWithoutExtension(cvmFile.Name);

                return(directory);
            }
        }
Пример #3
0
 void BuildViews()
 {
     if (streamView == null)
     {
         // We initialize the streamview and keep a reference to it here because
         // both the ActivityStreamView and the SingleLineStreamView use this instace
         // and only effect the visual templates shown. This would not be the
         // best reference implementation for implementing stream views but in this
         // case it gets the job done.
         streamView = new StreamView();
         view1      = new ActivityStreamViewHelper(state, streamView);
         view2      = new SingleLineViewHelper(state, streamView);
     }
 }
Пример #4
0
        public void Test_STREAM_VIEW_2()
        {
            Stream        b    = null;
            List <Sector> temp = new List <Sector>();

            StreamView sv = new StreamView(temp, 512, b);

            sv.Write(BitConverter.GetBytes(1), 0, 4);
            sv.Seek(0, SeekOrigin.Begin);
            BinaryReader br = new BinaryReader(sv);
            Int32        t  = br.ReadInt32();

            Assert.IsTrue(t == 1);
        }
Пример #5
0
        private string GetTitle(StreamView view)
        {
            switch (view)
            {
            case StreamView.ExpandedView:
                return(Strings.Resources.StreamViewExpanded);

            case StreamView.ListView:
                return(Strings.Resources.StreamViewList);

            default:
                return(view.ToString("G"));
            }
        }
        public static CryptoStream CreateDecryptorStream(Stream source, bool readHeader = true, bool skipSignature = false)
        {
            var decryptor = sAesManaged.CreateDecryptor();

            if (!readHeader)
            {
                return(new CryptoStream(source, decryptor, CryptoStreamMode.Read));
            }

            ReadHeader(source, skipSignature, out uint encryptedSize, out _);

            var streamView = new StreamView(source, source.Position, encryptedSize, true);

            return(new CryptoStream(streamView, decryptor, CryptoStreamMode.Read));
        }
Пример #7
0
        public void TEST_STREAM_VIEW()
        {
            Stream        a    = null;
            List <Sector> temp = new List <Sector>();
            Sector        s    = new Sector(512);

            Buffer.BlockCopy(BitConverter.GetBytes((int)1), 0, s.GetData(), 0, 4);
            temp.Add(s);

            StreamView   sv = new StreamView(temp, 512, 0, null, a);
            BinaryReader br = new BinaryReader(sv);
            Int32        t  = br.ReadInt32();

            Assert.IsTrue(t == 1);
        }
Пример #8
0
        public void Test_STREAM_VIEW_LARGE_DATA()
        {
            Stream        b    = null;
            List <Sector> temp = new List <Sector>();

            StreamView sv = new StreamView(temp, 512, b);

            for (int i = 0; i < 200; i++)
            {
                sv.Write(BitConverter.GetBytes(i), 0, 4);
            }

            sv.Seek(0, SeekOrigin.Begin);
            BinaryReader br = new BinaryReader(sv);

            for (int i = 0; i < 200; i++)
            {
                Assert.IsTrue(i == br.ReadInt32(), "Failed with " + i.ToString());
            }
        }
Пример #9
0
        /// <summary>
        /// Tries to open a file for reading.
        /// </summary>
        /// <param name="hash">Hash of the file.</param>
        /// <param name="stream">Readable stream of the file's data.</param>
        /// <returns>Whether the operation succeeded or not.</returns>
        public bool TryOpenFile(uint hash, out Stream stream)
        {
            if (!TryGetFileEntry(hash, out var entry))
            {
                stream = null;
                return(false);
            }

            stream = new StreamView(mStream, entry.Offset, entry.CompressedSize);
            var headerBytes = new byte[2];

            stream.Read(headerBytes, 0, 2);

            if (headerBytes[0] == 0x78)
            {
                stream = new DeflateStream(stream, CompressionMode.Decompress);
            }
            else
            {
                stream.Seek(-2, SeekOrigin.Current);
            }

            return(true);
        }
        /// <summary>
        ///     Sets the data for the current stream
        /// </summary>
        /// <param name="cfItem"></param>
        /// <param name="buffer"></param>
        /// <exception cref="CFException">Raised when <see cref="buffer" /> is null</exception>
        private void SetStreamData(CFItem cfItem, Byte[] buffer)
        {
            if (buffer == null)
                throw new CFException("Parameter [buffer] cannot be null");

            // Quick and dirty :-)
            if (buffer.Length == 0) return;

            var directoryEntry = cfItem.DirEntry;

            var sectorType = SectorType.Normal;
            var sectorSize = GetSectorSize();

            if (buffer.Length < _header.MinSizeStandardStream)
            {
                sectorType = SectorType.Mini;
                sectorSize = Sector.MinisectorSize;
            }

            // Check for transition ministream -> stream:
            // Only in this case we need to free old sectors,
            // otherwise they will be overwritten.

            if (directoryEntry.StartSector != Sector.Endofchain)
            {
                if (
                    (buffer.Length < _header.MinSizeStandardStream &&
                     directoryEntry.Size > _header.MinSizeStandardStream)
                    ||
                    (buffer.Length > _header.MinSizeStandardStream &&
                     directoryEntry.Size < _header.MinSizeStandardStream)
                    )
                {
                    if (directoryEntry.Size < _header.MinSizeStandardStream)
                    {
                        FreeMiniChain(GetMiniSectorChain(directoryEntry.StartSector), _eraseFreeSectors);
                    }
                    else
                    {
                        FreeChain(GetNormalSectorChain(directoryEntry.StartSector), _eraseFreeSectors);
                    }

                    directoryEntry.Size = 0;
                    directoryEntry.StartSector = Sector.Endofchain;
                }
            }

            var sectorChain
                = GetSectorChain(directoryEntry.StartSector, sectorType);

            Queue<Sector> freeList = null;

            if (_sectorRecycle)
                freeList = FindFreeSectors(sectorType); // Collect available free sectors

            var streamView = new StreamView(sectorChain, sectorSize, buffer.Length, freeList, SourceStream);

            streamView.Write(buffer, 0, buffer.Length);

            switch (sectorType)
            {
                case SectorType.Normal:
                    SetNormalSectorChain(streamView.BaseSectorChain);
                    break;

                case SectorType.Mini:
                    SetMiniSectorChain(streamView.BaseSectorChain);
                    break;
            }

            if (streamView.BaseSectorChain.Count > 0)
            {
                directoryEntry.StartSector = streamView.BaseSectorChain[0].Id;
                directoryEntry.Size = buffer.Length;
            }
            else
            {
                directoryEntry.StartSector = Sector.Endofchain;
                directoryEntry.Size = 0;
            }
        }
        /// <summary>
        ///     Allocate space, setup sectors id and refresh header
        ///     for the new or updated mini sector chain.
        /// </summary>
        /// <param name="sectorChain">The new MINI sector chain</param>
        private void SetMiniSectorChain(IList<Sector> sectorChain)
        {
            var miniFAT
                = GetSectorChain(_header.FirstMiniFATSectorId, SectorType.Normal);

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

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

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

            // Set updated/new sectors within the ministream
            foreach (var sector in sectorChain)
            {
                if (sector.Id != -1)
                {
                    // Overwrite
                    miniStreamView.Seek(Sector.MinisectorSize*sector.Id, SeekOrigin.Begin);
                    miniStreamView.Write(sector.GetData(), 0, Sector.MinisectorSize);
                }
                else
                {
                    // Allocate, position ministream at the end of already allocated
                    // ministream's sectors

                    miniStreamView.Seek(RootStorage.Size, SeekOrigin.Begin);
                    miniStreamView.Write(sector.GetData(), 0, Sector.MinisectorSize);
                    sector.Id = (int) (miniStreamView.Position - Sector.MinisectorSize)/Sector.MinisectorSize;

                    RootStorage.DirEntry.Size = miniStreamView.Length;
                }
            }

            // Update miniFAT
            for (var i = 0; i < sectorChain.Count - 1; i++)
            {
                var currentId = sectorChain[i].Id;
                var nextId = sectorChain[i + 1].Id;

                //AssureLength(miniFATView, Math.Max(currentId * SIZE_OF_SID, nextId * SIZE_OF_SID));

                miniFATView.Seek(currentId*4, SeekOrigin.Begin);
                miniFATView.Write(BitConverter.GetBytes(nextId), 0, 4);
            }

            // Write End of Chain in MiniFAT
            miniFATView.Seek(sectorChain[sectorChain.Count - 1].Id*SizeOfSID, SeekOrigin.Begin);
            miniFATView.Write(BitConverter.GetBytes(Sector.Endofchain), 0, 4);

            // Update sector chains
            SetNormalSectorChain(miniStreamView.BaseSectorChain);
            SetNormalSectorChain(miniFATView.BaseSectorChain);

            //Update HEADER and root storage when ministream changes
            if (miniFAT.Count > 0)
            {
                RootStorage.DirEntry.StartSector = miniStream[0].Id;
                _header.MiniFATSectorsNumber = (uint) miniFAT.Count;
                _header.FirstMiniFATSectorId = miniFAT[0].Id;
            }
        }
        /// <summary>
        ///     Allocate space, setup sectors id and refresh header
        ///     for the new or updated FAT sector chain.
        /// </summary>
        /// <param name="sectorChain">The new or updated generic sector chain</param>
        private void SetFATSectorChain(IList<Sector> sectorChain)
        {
            var fatSectors = GetSectorChain(-1, SectorType.FAT);
            var fatStream =
                new StreamView(
                    fatSectors,
                    GetSectorSize(),
                    _header.FATSectorsNumber*GetSectorSize(), SourceStream
                    );

            // Write FAT chain values --

            for (var i = 0; i < sectorChain.Count - 1; i++)
            {
                var sN = sectorChain[i + 1];
                var sC = sectorChain[i];

                fatStream.Seek(sC.Id*4, SeekOrigin.Begin);
                fatStream.Write(BitConverter.GetBytes(sN.Id), 0, 4);
            }

            fatStream.Seek(sectorChain[sectorChain.Count - 1].Id*4, SeekOrigin.Begin);
            fatStream.Write(BitConverter.GetBytes(Sector.Endofchain), 0, 4);

            // Merge chain to CFS
            SetDIFATSectorChain(fatStream.BaseSectorChain);
        }
Пример #13
0
        public override async Task ExecuteResultAsync(IWebDavResponse response, CancellationToken ct)
        {
            await base.ExecuteResultAsync(response, ct).ConfigureAwait(false);

            response.Headers["Accept-Ranges"] = new[] { "bytes" };

            var properties = await _document.GetProperties(response.Dispatcher).ToList(ct).ConfigureAwait(false);

            var etagProperty = properties.OfType <GetETagProperty>().FirstOrDefault();

            if (etagProperty != null)
            {
                var propValue = await etagProperty.GetValueAsync(ct).ConfigureAwait(false);

                response.Headers["ETag"] = new[] { propValue.ToString() };
            }

            if (!_returnFile)
            {
                var lastModifiedProp = properties.OfType <LastModifiedProperty>().FirstOrDefault();
                if (lastModifiedProp != null)
                {
                    var propValue = await lastModifiedProp.GetValueAsync(ct).ConfigureAwait(false);

                    response.Headers["Last-Modified"] = new[] { propValue.ToString("R") };
                }

                return;
            }

            var views = new List <StreamView>();

            try
            {
                foreach (var rangeItem in _rangeItems)
                {
                    var baseStream = await _document.OpenReadAsync(ct).ConfigureAwait(false);

                    var streamView = await StreamView
                                     .CreateAsync(baseStream, rangeItem.From, rangeItem.Length, ct)
                                     .ConfigureAwait(false);

                    views.Add(streamView);
                }

                string contentType;
                var    contentTypeProp = properties.OfType <GetContentTypeProperty>().FirstOrDefault();
                if (contentTypeProp != null)
                {
                    contentType = await contentTypeProp.GetValueAsync(ct).ConfigureAwait(false);
                }
                else
                {
                    contentType = MimeTypesMap.DefaultMimeType;
                }

                HttpContent content;
                if (_rangeItems.Count == 1)
                {
                    // No multipart content
                    var rangeItem  = _rangeItems.Single();
                    var streamView = views.Single();
                    content = new StreamContent(streamView);
                    try
                    {
                        content.Headers.ContentRange  = new ContentRangeHeaderValue(rangeItem.From, rangeItem.To, _document.Length);
                        content.Headers.ContentLength = rangeItem.Length;
                    }
                    catch
                    {
                        content.Dispose();
                        throw;
                    }

                    content.Headers.ContentType = MediaTypeHeaderValue.Parse(contentType);
                }
                else
                {
                    // Multipart content
                    var multipart = new MultipartContent("byteranges");
                    try
                    {
                        var index = 0;
                        foreach (var rangeItem in _rangeItems)
                        {
                            var streamView  = views[index++];
                            var partContent = new StreamContent(streamView);
                            partContent.Headers.ContentRange  = new ContentRangeHeaderValue(rangeItem.From, rangeItem.To, _document.Length);
                            partContent.Headers.ContentType   = MediaTypeHeaderValue.Parse(contentType);
                            partContent.Headers.ContentLength = rangeItem.Length;
                            multipart.Add(partContent);
                        }
                    }
                    catch
                    {
                        multipart.Dispose();
                        throw;
                    }

                    content = multipart;
                }

                using (content)
                {
                    await SetPropertiesToContentHeaderAsync(content, properties, ct)
                    .ConfigureAwait(false);

                    foreach (var header in content.Headers)
                    {
                        response.Headers.Add(header.Key, header.Value.ToArray());
                    }

                    await content.CopyToAsync(response.Body).ConfigureAwait(false);
                }
            }
            finally
            {
                foreach (var streamView in views)
                {
                    streamView.Dispose();
                }
            }
        }
        /// <summary>
        ///     Gets data from the <see cref="cFStream" />
        /// </summary>
        /// <param name="cFStream"></param>
        /// <returns></returns>
        /// <exception cref="CFDisposedException">Raised when the file is closed</exception>
        internal byte[] GetData(CFStream cFStream)
        {
            if (IsClosed)
                throw new CFDisposedException("Compound File closed: cannot access data");

            byte[] result;

            var directoryEntry = cFStream.DirEntry;

            if (directoryEntry.Size < _header.MinSizeStandardStream)
            {
                var miniView
                    = new StreamView(GetSectorChain(directoryEntry.StartSector, SectorType.Mini), Sector.MinisectorSize,
                        directoryEntry.Size,
                        SourceStream);

                var br = new BinaryReader(miniView);

                result = br.ReadBytes((int) directoryEntry.Size);
                br.Close();
            }
            else
            {
                var sView
                    = new StreamView(GetSectorChain(directoryEntry.StartSector, SectorType.Normal), GetSectorSize(),
                        directoryEntry.Size,
                        SourceStream);

                result = new byte[(int) directoryEntry.Size];

                sView.Read(result, 0, result.Length);
            }

            return result;
        }
        /// <summary>
        ///     Get the FAT sector chain
        /// </summary>
        /// <returns>List of FAT sectors</returns>
        private List<Sector> GetFatSectorChain()
        {
            const int numberOfHeaderFATEntry = 109; //Number of FAT sectors id in the header

            var result
                = new List<Sector>();

            int nextSecId;

            var difatSectors = GetDifatSectorChain();

            var idx = 0;

            // Read FAT entries from the header Fat entry array (max 109 entries)
            while (idx < _header.FATSectorsNumber && idx < numberOfHeaderFATEntry)
            {
                nextSecId = _header.DIFAT[idx];
                var sector = _sectors[nextSecId];

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

                result.Add(sector);

                idx++;
            }

            //Is there any DIFAT sector containing other FAT entries ?
            if (difatSectors.Count <= 0) return result;
            var difatStream
                = new StreamView
                    (
                    difatSectors,
                    GetSectorSize(),
                    _header.FATSectorsNumber > numberOfHeaderFATEntry
                        ? (_header.FATSectorsNumber - numberOfHeaderFATEntry)*4
                        : 0,
                    SourceStream
                    );

            var nextDIFATSectorBuffer = new byte[4];

            difatStream.Read(nextDIFATSectorBuffer, 0, 4);
            nextSecId = BitConverter.ToInt32(nextDIFATSectorBuffer, 0);

            var i = 0;
            var numberOfFatHeaderEntries = numberOfHeaderFATEntry;

            while (numberOfFatHeaderEntries < _header.FATSectorsNumber)
            {
                if (difatStream.Position == ((GetSectorSize() - 4) + i*GetSectorSize()))
                {
                    difatStream.Seek(4, SeekOrigin.Current);
                    i++;
                    continue;
                }

                var sector = _sectors[nextSecId];

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

                result.Add(sector);

                difatStream.Read(nextDIFATSectorBuffer, 0, 4);
                nextSecId = BitConverter.ToInt32(nextDIFATSectorBuffer, 0);
                numberOfFatHeaderEntries++;
            }

            return result;
        }
        private void FreeMiniChain(IList<Sector> sectorChain, bool zeroSector)
        {
            var zeroedMiniSector = new byte[Sector.MinisectorSize];

            var miniFAT
                = GetSectorChain(_header.FirstMiniFATSectorId, SectorType.Normal);

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

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

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

            // Set updated/new sectors within the ministream
            if (zeroSector)
            {
                foreach (var sector in sectorChain)
                {
                    if (sector.Id == -1) continue;
                    // Overwrite
                    miniStreamView.Seek(Sector.MinisectorSize*sector.Id, SeekOrigin.Begin);
                    miniStreamView.Write(zeroedMiniSector, 0, Sector.MinisectorSize);
                }
            }

            // Update miniFAT
            for (var i = 0; i < sectorChain.Count - 1; i++)
            {
                var currentId = sectorChain[i].Id;
                miniFATView.Seek(currentId*4, SeekOrigin.Begin);
                miniFATView.Write(BitConverter.GetBytes(Sector.FreeSector), 0, 4);
            }

            //AssureLength(miniFATView, sectorChain[sectorChain.Count - 1].Id * SIZE_OF_SID);

            // Write End of Chain in MiniFAT
            miniFATView.Seek(sectorChain[sectorChain.Count - 1].Id*SizeOfSID, SeekOrigin.Begin);
            miniFATView.Write(BitConverter.GetBytes(Sector.FreeSector), 0, 4);

            // Update sector chains
            SetNormalSectorChain(miniStreamView.BaseSectorChain);
            SetNormalSectorChain(miniFATView.BaseSectorChain);

            //Update HEADER and root storage when ministream changes
            if (miniFAT.Count > 0)
            {
                RootStorage.DirEntry.StartSector = miniStream[0].Id;
                _header.MiniFATSectorsNumber = (uint) miniFAT.Count;
                _header.FirstMiniFATSectorId = miniFAT[0].Id;
            }
        }
        private void FreeChain(IList<Sector> sectorChain, bool zeroSector)
        {
            var fat = GetSectorChain(-1, SectorType.FAT);

            var fatView = new StreamView(fat, GetSectorSize(), fat.Count*GetSectorSize(), SourceStream);

            // Zeroes out sector data (if requested)
            if (zeroSector)
            {
                foreach (var sector in sectorChain)
                    sector.ZeroData();
            }

            // Update FAT marking unallocated sectors
            for (var i = 0; i < sectorChain.Count - 1; i++)
            {
                var currentId = sectorChain[i].Id;

                //AssureLength(FATView, Math.Max(currentId * SIZE_OF_SID, nextId * SIZE_OF_SID));

                fatView.Seek(currentId*4, SeekOrigin.Begin);
                fatView.Write(BitConverter.GetBytes(Sector.FreeSector), 0, 4);
            }
        }
        /// <summary>
        ///     Commit directory entries change on the Current Source stream
        /// </summary>
        private void CommitDirectory()
        {
            const int directorySize = 128;

            var directorySectors
                = GetSectorChain(_header.FirstDirectorySectorId, SectorType.Normal);

            var sv = new StreamView(directorySectors, GetSectorSize(), 0, SourceStream);

            foreach (var directoryEntry in _directoryEntries)
                directoryEntry.Write(sv);

            var delta = _directoryEntries.Count;

            while (delta%(GetSectorSize()/directorySize) != 0)
            {
                var dummy = new DirectoryEntry(StgType.StgInvalid);
                dummy.Write(sv);
                delta++;
            }

            foreach (var s in directorySectors)
            {
                s.Type = SectorType.Directory;
            }

            SetNormalSectorChain(directorySectors);

            _header.FirstDirectorySectorId = directorySectors[0].Id;

            // Version 4 supports directory sectors count
            _header.DirectorySectorsNumber = _header.MajorVersion == 3 ? 0 : directorySectors.Count;
        }
        /// <summary>
        ///     Check for transaction lock sector addition and mark it in the FAT.
        /// </summary>
        private void CheckForLockSector()
        {
            //If transaction lock has been added and not yet allocated in the FAT...
            if (TransactionLockAdded && !TransactionLockAllocated)
            {
                var fatStream = new StreamView(GetFatSectorChain(), GetSectorSize(), SourceStream);

                fatStream.Seek(LockSectorId*4, SeekOrigin.Begin);
                fatStream.Write(BitConverter.GetBytes(Sector.Endofchain), 0, 4);

                TransactionLockAllocated = true;
            }
        }
Пример #20
0
 public ActivityStreamViewHelper(ConversationsState state, StreamView view)
 {
     this.state = state;
     this.view  = view;
 }
        /// <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;
        }
        /// <summary>
        ///     Gets data from the <see cref="cFStream" />
        /// </summary>
        /// <param name="cFStream"></param>
        /// <param name="offset"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        /// <exception cref="CFDisposedException">Raised when the file is closed</exception>
        internal byte[] GetData(CFStream cFStream, long offset, ref int count)
        {
            var directoryEntry = cFStream.DirEntry;
            count = (int) Math.Min(directoryEntry.Size - offset, count);

            StreamView streamView;

            if (directoryEntry.Size < _header.MinSizeStandardStream)
            {
                streamView
                    = new StreamView(GetSectorChain(directoryEntry.StartSector, SectorType.Mini), Sector.MinisectorSize,
                        directoryEntry.Size,
                        SourceStream);
            }
            else
            {
                streamView = new StreamView(GetSectorChain(directoryEntry.StartSector, SectorType.Normal),
                    GetSectorSize(), directoryEntry.Size,
                    SourceStream);
            }

            var result = new byte[count];
            streamView.Seek(offset, SeekOrigin.Begin);
            streamView.Read(result, 0, result.Length);

            return result;
        }
Пример #23
0
 public StreamViewItem(StreamView view)
 {
     View  = view;
     Title = GetTitle(view);
 }
 public SingleLineViewHelper(ConversationsState state, StreamView view)
 {
     this.state = state;
     this.view  = view;
 }
Пример #25
0
        private string GetTitle(StreamView view)
        {
            switch (view)
            {
                case StreamView.ExpandedView:
                    return Strings.Resources.StreamViewExpanded;

                case StreamView.ListView:
                    return Strings.Resources.StreamViewList;

                default:
                    return view.ToString("G");
            }
        }
        /// <summary>
        ///     Load directory entries from compound file. Header and FAT MUST be already loaded.
        /// </summary>
        private void LoadDirectories()
        {
            var directoryChain
                = GetSectorChain(_header.FirstDirectorySectorId, SectorType.Normal);

            if (_header.FirstDirectorySectorId == Sector.Endofchain)
                _header.FirstDirectorySectorId = directoryChain[0].Id;

            var dirReader
                = new StreamView(directoryChain, GetSectorSize(), directoryChain.Count*GetSectorSize(), SourceStream);

            while (dirReader.Position < directoryChain.Count*GetSectorSize())
            {
                var de
                    = new DirectoryEntry(StgType.StgInvalid);

                //We are not inserting dirs. Do not use 'InsertNewDirectoryEntry'
                de.Read(dirReader);
                _directoryEntries.Add(de);
                de.SID = _directoryEntries.Count - 1;
            }
        }
        /// <summary>
        ///     Setup the DIFAT sector chain
        /// </summary>
        /// <param name="faTsectorChain">A FAT sector chain</param>
        private void SetDIFATSectorChain(List<Sector> faTsectorChain)
        {
            // Get initial sector's count
            _header.FATSectorsNumber = faTsectorChain.Count;

            // Allocate Sectors
            foreach (var s in faTsectorChain)
            {
                if (s.Id != -1) continue;
                _sectors.Add(s);
                s.Id = _sectors.Count - 1;
                s.Type = SectorType.FAT;
            }

            // Sector count...
            var nCurrentSectors = _sectors.Count;

            // Temp DIFAT count
            var nDIFATSectors = (int) _header.DIFATSectorsNumber;

            if (faTsectorChain.Count > HeaderDIFATEntriesCount)
            {
                nDIFATSectors =
                    Ceiling((double) (faTsectorChain.Count - HeaderDIFATEntriesCount)/_difatSectorFATEntriesCount);
                nDIFATSectors = LowSaturation(nDIFATSectors - (int) _header.DIFATSectorsNumber); //required DIFAT
            }

            // ...sum with new required DIFAT sectors count
            nCurrentSectors += nDIFATSectors;

            // ReCheck FAT bias
            while (_header.FATSectorsNumber*_fatSectorEntriesCount < nCurrentSectors)
            {
                var extraFATSector = new Sector(GetSectorSize(), SourceStream);
                _sectors.Add(extraFATSector);

                extraFATSector.Id = _sectors.Count - 1;
                extraFATSector.Type = SectorType.FAT;

                faTsectorChain.Add(extraFATSector);

                _header.FATSectorsNumber++;
                nCurrentSectors++;

                //... so, adding a FAT sector may induce DIFAT sectors to increase by one
                // and consequently this may induce ANOTHER FAT sector (TO-THINK: May this condition occure ?)
                if (nDIFATSectors*_difatSectorFATEntriesCount >= (_header.FATSectorsNumber > HeaderDIFATEntriesCount
                    ? _header.FATSectorsNumber - HeaderDIFATEntriesCount
                    : 0)) continue;
                nDIFATSectors++;
                nCurrentSectors++;
            }

            var difatSectors = GetSectorChain(-1, SectorType.DIFAT);

            var difatStream = new StreamView(difatSectors, GetSectorSize(), SourceStream);

            // Write DIFAT Sectors (if required)
            // Save room for the following chaining
            for (var i = 0; i < faTsectorChain.Count; i++)
            {
                if (i < HeaderDIFATEntriesCount)
                    _header.DIFAT[i] = faTsectorChain[i].Id;
                else
                {
                    // room for DIFAT chaining at the end of any DIFAT sector (4 bytes)
                    if (i != HeaderDIFATEntriesCount &&
                        (i - HeaderDIFATEntriesCount)%_difatSectorFATEntriesCount == 0)
                    {
                        var temp = new byte[sizeof (int)];
                        difatStream.Write(temp, 0, sizeof (int));
                    }

                    difatStream.Write(BitConverter.GetBytes(faTsectorChain[i].Id), 0, sizeof (int));
                }
            }

            // Allocate room for DIFAT sectors
            foreach (var sector in difatStream.BaseSectorChain)
            {
                if (sector.Id != -1) continue;
                _sectors.Add(sector);
                sector.Id = _sectors.Count - 1;
                sector.Type = SectorType.DIFAT;
            }

            _header.DIFATSectorsNumber = (uint) nDIFATSectors;

            // Chain first sector
            if (difatStream.BaseSectorChain != null && difatStream.BaseSectorChain.Count > 0)
            {
                _header.FirstDIFATSectorId = difatStream.BaseSectorChain[0].Id;

                // Update header information
                _header.DIFATSectorsNumber = (uint) difatStream.BaseSectorChain.Count;

                // Write chaining information at the end of DIFAT Sectors
                for (var i = 0; i < difatStream.BaseSectorChain.Count - 1; i++)
                {
                    Buffer.BlockCopy(
                        BitConverter.GetBytes(difatStream.BaseSectorChain[i + 1].Id),
                        0,
                        difatStream.BaseSectorChain[i].GetData(),
                        GetSectorSize() - sizeof (int),
                        4);
                }

                Buffer.BlockCopy(
                    BitConverter.GetBytes(Sector.Endofchain),
                    0,
                    difatStream.BaseSectorChain[difatStream.BaseSectorChain.Count - 1].GetData(),
                    GetSectorSize() - sizeof (int),
                    sizeof (int)
                    );
            }
            else
                _header.FirstDIFATSectorId = Sector.Endofchain;

            // Mark DIFAT Sectors in FAT
            var fatSv = new StreamView(faTsectorChain, GetSectorSize(), _header.FATSectorsNumber*GetSectorSize(),
                SourceStream);

            for (var i = 0; i < _header.DIFATSectorsNumber; i++)
            {
                fatSv.Seek(difatStream.BaseSectorChain[i].Id*4, SeekOrigin.Begin);
                fatSv.Write(BitConverter.GetBytes(Sector.DifSector), 0, 4);
            }

            for (var i = 0; i < _header.FATSectorsNumber; i++)
            {
                fatSv.Seek(fatSv.BaseSectorChain[i].Id*4, SeekOrigin.Begin);
                fatSv.Write(BitConverter.GetBytes(Sector.FATSector), 0, 4);
            }

            _header.FATSectorsNumber = fatSv.BaseSectorChain.Count;
        }
        /// <summary>
        ///     Get a mini sector chain
        /// </summary>
        /// <param name="sectorId">First sector id of the required chain</param>
        /// <returns>A list of mini sectors (64 bytes)</returns>
        private List<Sector> GetMiniSectorChain(int sectorId)
        {
            var result = new List<Sector>();

            if (sectorId == Sector.Endofchain) return result;
            var miniFAT = GetNormalSectorChain(_header.FirstMiniFATSectorId);
            var miniStream = GetNormalSectorChain(RootEntry.StartSector);

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

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

            var miniFATReader = new BinaryReader(miniFATView);

            var nextSectorId = sectorId;

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

                var miniSector = new Sector(Sector.MinisectorSize, SourceStream)
                {
                    Id = nextSectorId,
                    Type = SectorType.Mini
                };

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

                result.Add(miniSector);

                miniFATView.Seek(nextSectorId*4, SeekOrigin.Begin);
                nextSectorId = miniFATReader.ReadInt32();
            }
            return result;
        }
Пример #29
0
        public override async Task ExecuteResultAsync(IWebDavResponse response, CancellationToken ct)
        {
            await base.ExecuteResultAsync(response, ct);

            response.Headers["Accept-Ranges"] = new[] { "bytes" };

            var properties = await _document.GetProperties(response.Dispatcher).ToList(ct);

            var etagProperty = properties.OfType <GetETagProperty>().FirstOrDefault();

            if (etagProperty != null)
            {
                var propValue = await etagProperty.GetValueAsync(ct);

                response.Headers["ETag"] = new[] { propValue.ToString() };
            }

            if (!_returnFile)
            {
                var lastModifiedProp = properties.OfType <LastModifiedProperty>().FirstOrDefault();
                if (lastModifiedProp != null)
                {
                    var propValue = await lastModifiedProp.GetValueAsync(ct);

                    response.Headers["Last-Modified"] = new[] { propValue.ToString("R") };
                }

                return;
            }

            var views = new List <StreamView>();

            try
            {
                foreach (var rangeItem in _rangeItems)
                {
                    var baseStream = await _document.OpenReadAsync(ct);

                    var streamView = await StreamView
                                     .CreateAsync(baseStream, rangeItem.From, rangeItem.Length, ct)
                    ;

                    views.Add(streamView);
                }

                string contentType;
                var    contentTypeProp = properties.OfType <GetContentTypeProperty>().FirstOrDefault();
                if (contentTypeProp != null)
                {
                    contentType = await contentTypeProp.GetValueAsync(ct);
                }
                else
                {
                    contentType = MimeTypesMap.DefaultMimeType;
                }

                if (_rangeItems.Count == 1)
                {
                    // No multipart content
                    var rangeItem  = _rangeItems.Single();
                    var streamView = views.Single();
                    using (var streamContent = new StreamContent(streamView))
                    {
                        streamContent.Headers.ContentRange = new ContentRangeHeaderValue(
                            rangeItem.From,
                            rangeItem.To,
                            _document.Length);
                        streamContent.Headers.ContentLength = rangeItem.Length;

                        streamContent.Headers.ContentType = MediaTypeHeaderValue.Parse(contentType);

                        await SetPropertiesToContentHeaderAsync(streamContent, properties, ct)
                        ;

                        foreach (var header in streamContent.Headers)
                        {
                            response.Headers.Add(header.Key, header.Value.ToArray());
                        }

                        // Use the CopyToAsync function of the stream itself, because
                        // we're able to pass the cancellation token. This is a workaround
                        // for issue dotnet/corefx#9071 and fixes FubarDevelopment/WebDavServer#47.
                        await streamView.CopyToAsync(response.Body, 81920, ct)
                        ;
                    }
                }
                else
                {
                    // Multipart content
                    using (var multipart = new MultipartContent("byteranges"))
                    {
                        var index = 0;
                        foreach (var rangeItem in _rangeItems)
                        {
                            var streamView  = views[index++];
                            var partContent = new StreamContent(streamView);
                            partContent.Headers.ContentRange = new ContentRangeHeaderValue(
                                rangeItem.From,
                                rangeItem.To,
                                _document.Length);
                            partContent.Headers.ContentType   = MediaTypeHeaderValue.Parse(contentType);
                            partContent.Headers.ContentLength = rangeItem.Length;
                            multipart.Add(partContent);
                        }

                        await SetPropertiesToContentHeaderAsync(multipart, properties, ct)
                        ;

                        foreach (var header in multipart.Headers)
                        {
                            response.Headers.Add(header.Key, header.Value.ToArray());
                        }

                        // TODO: Workaround for issue dotnet/corefx#9071
                        await multipart.CopyToAsync(response.Body);
                    }
                }
            }
            finally
            {
                foreach (var streamView in views)
                {
                    streamView.Dispose();
                }
            }
        }
        /// <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;
        }
Пример #31
0
 public StreamViewItem(StreamView view)
 {
     View = view;
     Title = GetTitle(view);
 }