Exemple #1
0
        public void CreateWholeDisk()
        {
            long capacity         = 3 * 1024 * 1024;
            SparseMemoryStream ms = new SparseMemoryStream();

            ms.SetLength(capacity);
            Geometry           geom  = Geometry.FromCapacity(capacity);
            BiosPartitionTable table = BiosPartitionTable.Initialize(ms, geom);

            int idx = table.Create(WellKnownPartitionType.WindowsFat, true);

            // Make sure the partition fills all but the first track on the disk.
            Assert.AreEqual(geom.TotalSectors, table[idx].SectorCount + geom.SectorsPerTrack);

            // Make sure FAT16 was selected for a disk of this size
            Assert.AreEqual(BiosPartitionTypes.Fat16, table[idx].BiosType);

            // Make sure partition starts where expected
            Assert.AreEqual(new ChsAddress(0, 1, 1), ((BiosPartitionInfo)table[idx]).Start);

            // Make sure partition ends at end of disk
            Assert.AreEqual(geom.ToLogicalBlockAddress(geom.LastSector), table[idx].LastSector);
            Assert.AreEqual(geom.LastSector, ((BiosPartitionInfo)table[idx]).End);

            // Make sure the 'active' flag made it through...
            Assert.IsTrue(((BiosPartitionInfo)table[idx]).IsActive);

            // Make sure the partition index is Zero
            Assert.AreEqual(0, ((BiosPartitionInfo)table[idx]).PrimaryIndex);
        }
Exemple #2
0
        public void HonoursReadOnly()
        {
            SparseMemoryStream diskStream = new SparseMemoryStream();
            FatFileSystem      fs         = FatFileSystem.FormatFloppy(diskStream, FloppyDiskType.HighDensity, "FLOPPY_IMG ");

            fs.CreateDirectory(@"AAA");
            fs.CreateDirectory(@"BAR");
            using (Stream t = fs.OpenFile(@"BAR\AAA.TXT", FileMode.Create, FileAccess.ReadWrite)) { }
            using (Stream s = fs.OpenFile(@"BAR\FOO.TXT", FileMode.Create, FileAccess.ReadWrite))
            {
                StreamWriter w = new StreamWriter(s);
                w.WriteLine("FOO - some sample text");
                w.Flush();
            }
            fs.SetLastAccessTimeUtc(@"BAR", new DateTime(1980, 1, 1));
            fs.SetLastAccessTimeUtc(@"BAR\FOO.TXT", new DateTime(1980, 1, 1));

            // Check we can access a file without any errors
            SparseStream  roDiskStream = SparseStream.ReadOnly(diskStream, Ownership.None);
            FatFileSystem fatFs        = new FatFileSystem(roDiskStream);

            using (Stream fileStream = fatFs.OpenFile(@"BAR\FOO.TXT", FileMode.Open))
            {
                fileStream.ReadByte();
            }
        }
Exemple #3
0
        /// <summary>
        /// Uses BinarySearch to locate the index of the block that contains start
        /// </summary>
        /// <param name="cache"></param>
        /// <param name="start"></param>
        /// <param name="match">True if match found.  If this is false, the index returned is where the item would appear if it existed.</param>
        /// <returns>Index</returns>
        private int FindIndexOfBlockAtOffset(SparseMemoryStream cache, long start, out bool match)
        {
            if (cache.MemoryBlockCollection.Count == 0)
            {
                match = false;
                return(0);
            }

            // use BinarySearch to locate blocks of interest quickly
            if (_comparisonBlock == null)
            {
                _comparisonBlock = new MemoryStreamBlock(null, start);
            }
            else
            {
                _comparisonBlock.Offset = start;
            }

            int index = cache.MemoryBlockCollection.BinarySearch(_comparisonBlock);

            if (index < 0) // no match
            {
                // ~index represents the place at which the block we asked for
                // would appear if it existed
                index = ~index;
                match = false;
            }
            else
            {
                match = true;
            }
            return(index);
        }
        public void ViewIO()
        {
            SparseMemoryStream memStream = new SparseMemoryStream();

            memStream.SetLength(1024);

            ThreadSafeStream tss = new ThreadSafeStream(memStream);

            SparseStream altView = tss.OpenView();

            // Check positions are independant
            tss.Position = 100;
            Assert.Equal(0, altView.Position);
            Assert.Equal(100, tss.Position);

            // Check I/O is synchronous
            byte[] buffer = new byte[200];
            tss.WriteByte(99);
            altView.Read(buffer, 0, 200);
            Assert.Equal(99, buffer[100]);

            // Check positions are updated correctly
            Assert.Equal(200, altView.Position);
            Assert.Equal(101, tss.Position);
        }
        /// <summary>
        /// Initializes a new instance of the BiosPartitionedDiskBuilder class by
        /// cloning the partition structure of a source disk.
        /// </summary>
        /// <param name="sourceDisk">The disk to clone.</param>
        public BiosPartitionedDiskBuilder(VirtualDisk sourceDisk)
        {
            if (sourceDisk == null)
            {
                throw new ArgumentNullException(nameof(sourceDisk));
            }

            _capacity     = sourceDisk.Capacity;
            _biosGeometry = sourceDisk.BiosGeometry;

            _bootSectors = new SparseMemoryStream();
            _bootSectors.SetLength(_capacity);

            foreach (StreamExtent extent in new BiosPartitionTable(sourceDisk).GetMetadataDiskExtents())
            {
                sourceDisk.Content.Position = extent.Start;
                byte[] buffer = StreamUtilities.ReadExact(sourceDisk.Content, (int)extent.Length);
                _bootSectors.Position = extent.Start;
                _bootSectors.Write(buffer, 0, buffer.Length);
            }

            PartitionTable = new BiosPartitionTable(_bootSectors, _biosGeometry);

            _partitionContents = new Dictionary <int, BuilderExtent>();
        }
        public static DiscUtils.Ntfs.NtfsFileSystem NtfsFileSystem()
        {
            SparseMemoryBuffer buffer       = new SparseMemoryBuffer(4096);
            SparseMemoryStream ms           = new SparseMemoryStream();
            Geometry           diskGeometry = Geometry.FromCapacity(30 * 1024 * 1024);

            return(DiscUtils.Ntfs.NtfsFileSystem.Format(ms, "", diskGeometry, 0, diskGeometry.TotalSectorsLong));
        }
        private static DiscFileSystem FatFileSystem()
        {
            SparseMemoryBuffer buffer       = new SparseMemoryBuffer(4096);
            SparseMemoryStream ms           = new SparseMemoryStream();
            Geometry           diskGeometry = Geometry.FromCapacity(30 * 1024 * 1024);

            return(DiscUtils.Fat.FatFileSystem.FormatFloppy(ms, FloppyDiskType.Extended, null));
        }
Exemple #8
0
        protected V8Container NewContainer()
        {
            var baseStream = SparseMemoryStream.WritableStream();
            var container  = new V8Container(baseStream, V8ContainerMode.Write);

            _disposables.Add(container);

            return(container);
        }
Exemple #9
0
        public void InvalidImageThrowsException()
        {
            SparseMemoryStream stream = new SparseMemoryStream();

            byte[] buffer = new byte[1024 * 1024];
            stream.Write(buffer, 0, 1024 * 1024);
            stream.Position = 0;
            Assert.Throws <InvalidFileSystemException>(() => new FatFileSystem(stream));
        }
        public void CreateBySizeInGap()
        {
            SparseMemoryStream ms = new SparseMemoryStream();
            Geometry geom = new Geometry(15, 30, 63);
            ms.SetLength(geom.Capacity);
            BiosPartitionTable table = BiosPartitionTable.Initialize(ms, geom);

            Assert.AreEqual(0, table.CreatePrimaryByCylinder(0, 4, 33, false));
            Assert.AreEqual(1, table.CreatePrimaryByCylinder(10, 14, 33, false));
            table.Create(geom.ToLogicalBlockAddress(new ChsAddress(4, 0, 1)) * 512, WellKnownPartitionType.WindowsFat, true);
        }
        public void CanRead()
        {
            SparseMemoryStream memStream = new SparseMemoryStream(new SparseMemoryBuffer(1), FileAccess.ReadWrite);
            ThreadSafeStream   tss       = new ThreadSafeStream(memStream);

            Assert.Equal(true, tss.CanRead);

            memStream = new SparseMemoryStream(new SparseMemoryBuffer(1), FileAccess.Write);
            tss       = new ThreadSafeStream(memStream);
            Assert.Equal(false, tss.CanRead);
        }
Exemple #12
0
        public void Format_LargeDisk()
        {
            long size = 1024L * 1024 * 1024L * 1024; // 1 TB
            SparseMemoryStream partStream = new SparseMemoryStream();

            NtfsFileSystem.Format(partStream, "New Partition", Geometry.FromCapacity(size), 0, size / 512);

            NtfsFileSystem ntfs = new NtfsFileSystem(partStream);

            ntfs.Dump(TextWriter.Null, "");
        }
        /// <summary>
        /// Initializes a new instance of the BiosPartitionedDiskBuilder class.
        /// </summary>
        /// <param name="capacity">The capacity of the disk (in bytes)</param>
        /// <param name="biosGeometry">The BIOS geometry of the disk</param>
        public BiosPartitionedDiskBuilder(long capacity, Geometry biosGeometry)
        {
            _capacity = capacity;
            _biosGeometry = biosGeometry;

            _bootSectors = new SparseMemoryStream();
            _bootSectors.SetLength(capacity);
            _partitionTable = BiosPartitionTable.Initialize(_bootSectors, _biosGeometry);

            _partitionContents = new Dictionary<int, BuilderExtent>();
        }
        /// <summary>
        /// Initializes a new instance of the BiosPartitionedDiskBuilder class.
        /// </summary>
        /// <param name="capacity">The capacity of the disk (in bytes)</param>
        /// <param name="biosGeometry">The BIOS geometry of the disk</param>
        public BiosPartitionedDiskBuilder(long capacity, Geometry biosGeometry)
        {
            _capacity     = capacity;
            _biosGeometry = biosGeometry;

            _bootSectors = new SparseMemoryStream();
            _bootSectors.SetLength(capacity);
            _partitionTable = BiosPartitionTable.Initialize(_bootSectors, _biosGeometry);

            _partitionContents = new Dictionary <int, BuilderExtent>();
        }
Exemple #15
0
        public void Initialize()
        {
            long capacity         = 3 * 1024 * 1024;
            SparseMemoryStream ms = new SparseMemoryStream();

            ms.SetLength(capacity);
            Geometry           geom  = Geometry.FromCapacity(capacity);
            BiosPartitionTable table = BiosPartitionTable.Initialize(ms, geom);

            Assert.AreEqual(0, table.Count);
        }
Exemple #16
0
        public void CreateBySizeInGap()
        {
            SparseMemoryStream ms   = new SparseMemoryStream();
            Geometry           geom = new Geometry(15, 30, 63);

            ms.SetLength(geom.Capacity);
            BiosPartitionTable table = BiosPartitionTable.Initialize(ms, geom);

            Assert.AreEqual(0, table.CreatePrimaryByCylinder(0, 4, 33, false));
            Assert.AreEqual(1, table.CreatePrimaryByCylinder(10, 14, 33, false));
            table.Create(geom.ToLogicalBlockAddress(new ChsAddress(4, 0, 1)) * 512, WellKnownPartitionType.WindowsFat, true);
        }
        public BiosPartitionedDiskBuilder(long capacity, byte[] bootSectors, Geometry biosGeometry)
        {
            _capacity     = capacity;
            _biosGeometry = biosGeometry;

            _bootSectors = new SparseMemoryStream();
            _bootSectors.SetLength(capacity);
            _bootSectors.Write(bootSectors, 0, bootSectors.Length);
            _partitionTable = new BiosPartitionTable(_bootSectors, biosGeometry);

            _partitionContents = new Dictionary <int, BuilderExtent>();
        }
Exemple #18
0
        public void Format_SmallDisk()
        {
            long size = 8 * 1024 * 1024;
            SparseMemoryStream partStream = new SparseMemoryStream();

            //VirtualDisk disk = Vhd.Disk.InitializeDynamic(partStream, Ownership.Dispose, size);
            NtfsFileSystem.Format(partStream, "New Partition", Geometry.FromCapacity(size), 0, size / 512);

            NtfsFileSystem ntfs = new NtfsFileSystem(partStream);

            ntfs.Dump(TextWriter.Null, "");
        }
        public BiosPartitionedDiskBuilder(long capacity, byte[] bootSectors, Geometry biosGeometry)
        {
            _capacity = capacity;
            _biosGeometry = biosGeometry;

            _bootSectors = new SparseMemoryStream();
            _bootSectors.SetLength(capacity);
            _bootSectors.Write(bootSectors, 0, bootSectors.Length);
            _partitionTable = new BiosPartitionTable(_bootSectors, biosGeometry);

            _partitionContents = new Dictionary<int, BuilderExtent>();
        }
        IDataTransform.GetTransformedStream(
            Stream encodedStream,
            IDictionary transformContext
            )
        {
            Stream tempStream = new SparseMemoryStream(_lowWaterMark, _highWaterMark);

            tempStream = new CompressEmulationStream(encodedStream, tempStream, 0, new CompoundFileDeflateTransform());

            // return a VersionedStream that works with the VersionedStreamOwner
            // to verify/update our FormatVersion info
            return(new VersionedStream(tempStream, _versionedStreamOwner));
        }
        public static DiscFileSystem DiagnosticNtfsFileSystem()
        {
            SparseMemoryBuffer buffer       = new SparseMemoryBuffer(4096);
            SparseMemoryStream ms           = new SparseMemoryStream();
            Geometry           diskGeometry = Geometry.FromCapacity(30 * 1024 * 1024);

            DiscUtils.Ntfs.NtfsFileSystem.Format(ms, "", diskGeometry, 0, diskGeometry.TotalSectorsLong);
            var discFs = new DiscUtils.Diagnostics.ValidatingFileSystem <NtfsFileSystem, NtfsFileSystemChecker>(ms);

            discFs.CheckpointInterval = 1;
            discFs.GlobalIOTraceCapturesStackTraces = false;
            return(discFs);
        }
Exemple #22
0
        public void VeryLargePartition()
        {
            long capacity         = 1300 * 1024L * 1024L * 1024;
            SparseMemoryStream ms = new SparseMemoryStream();

            ms.SetLength(capacity);
            Geometry           geom  = Geometry.LbaAssistedBiosGeometry(capacity);
            BiosPartitionTable table = BiosPartitionTable.Initialize(ms, geom);

            // exception occurs here
            int i = table.CreatePrimaryByCylinder(0, 150000, (byte)WellKnownPartitionType.WindowsNtfs, true);

            Assert.AreEqual(150000, geom.ToChsAddress(table[0].LastSector).Cylinder);
        }
Exemple #23
0
        public override void SetLength(long newLength)
        {
            CheckDisposed();

            Debug.Assert(_cachePrefixStream == null); // we only expect this thing to be not null during Archive Save execution
            // that would between PreSaveNotofication call and Save SaveStreaming

            if (newLength < 0)
            {
                throw new ArgumentOutOfRangeException("newLength");
            }

            if (_currentStreamLength != newLength)
            {
                _dirtyFlag   = true;
                _dataChanged = true;

                if (newLength <= _persistedSize)
                {
                    // the stream becomes smaller than our disk block, which means that
                    // we can drop the in-memory-sparse-suffix
                    if (_sparseMemoryStreamSuffix != null)
                    {
                        _sparseMemoryStreamSuffix.Close();
                        _sparseMemoryStreamSuffix = null;
                    }
                }
                else
                {
                    // we need to construct Sparse Memory stream if we do not have one yet
                    if (_sparseMemoryStreamSuffix == null)
                    {
                        _sparseMemoryStreamSuffix = new SparseMemoryStream(_lowWaterMark, _highWaterMark);
                    }

                    // set size on the Sparse Memory Stream
                    _sparseMemoryStreamSuffix.SetLength(newLength - _persistedSize); // no need for checked as it was verified above
                }

                _currentStreamLength = newLength;

                // if stream was truncated to the point that our current position is beyond the end of the stream,
                // we need to reset position so it is at the end of the stream
                if (_currentStreamLength < _currentStreamPosition)
                {
                    Seek(_currentStreamLength, SeekOrigin.Begin);
                }
            }
        }
        public void CreateByCylinder()
        {
            SparseMemoryStream ms = new SparseMemoryStream();
            Geometry geom = new Geometry(15, 30, 63);
            ms.SetLength(geom.Capacity);
            BiosPartitionTable table = BiosPartitionTable.Initialize(ms, geom);

            Assert.AreEqual(0, table.CreatePrimaryByCylinder(0, 4, 33, false));
            Assert.AreEqual(1, table.CreatePrimaryByCylinder(10, 14, 33, false));

            Assert.AreEqual(geom.ToLogicalBlockAddress(new ChsAddress(0, 1, 1)), table[0].FirstSector);
            Assert.AreEqual(geom.ToLogicalBlockAddress(new ChsAddress(5, 0, 1)) - 1, table[0].LastSector);
            Assert.AreEqual(geom.ToLogicalBlockAddress(new ChsAddress(10, 0, 1)), table[1].FirstSector);
            Assert.AreEqual(geom.ToLogicalBlockAddress(new ChsAddress(14, 29, 63)), table[1].LastSector);
        }
Exemple #25
0
        private int ReadFromCache(SparseMemoryStream cache, long start, int count, byte[] buffer, int bufferOffset)
        {
#if DEBUG
            // debug only check for valid parameters, as we generally expect callers to verify them
            PackagingUtilities.VerifyStreamReadArgs(this, buffer, bufferOffset, count);
#endif
            Debug.Assert(cache != null);
            Debug.Assert(start >= 0);
            IList <MemoryStreamBlock> collection = cache.MemoryBlockCollection;

            checked
            {
                // use BinarySearch to locate blocks of interest quickly
                bool match;     // exact match?
                int  index = FindIndexOfBlockAtOffset(cache, start, out match);

                // if match was found, read from it
                int bytesRead = 0;
                if (match)
                {
                    MemoryStreamBlock memStreamBlock = collection[index];
                    long overlapBlockOffset;
                    long overlapBlockSize;

                    // we have got an overlap which can be used to satisfy the read request,
                    // at least  partially
                    PackagingUtilities.CalculateOverlap(memStreamBlock.Offset, memStreamBlock.Stream.Length,
                                                        start, count,
                                                        out overlapBlockOffset, out overlapBlockSize);

                    if (overlapBlockSize > 0)
                    {
                        // overlap must be starting at the start as we know for sure that
                        // memStreamBlock.Offset <= start
                        Debug.Assert(overlapBlockOffset == start);

                        memStreamBlock.Stream.Seek(overlapBlockOffset - memStreamBlock.Offset, SeekOrigin.Begin);

                        // we know that memStream will return as much data as we requested
                        // even if this logic changes we do not have to return everything
                        // a partially complete read is acceptable here
                        bytesRead = memStreamBlock.Stream.Read(buffer, bufferOffset, (int)overlapBlockSize);
                    }
                }

                return(bytesRead);
            }
        }
        public DiskBuilderTest()
        {
            SparseMemoryStream sourceStream = new SparseMemoryStream();

            sourceStream.SetLength(160 * 1024L * 1024);
            for (int i = 0; i < 8; ++i)
            {
                sourceStream.Position = i * 1024L * 1024;
                sourceStream.WriteByte((byte)i);
            }

            sourceStream.Position = 150 * 1024 * 1024;
            sourceStream.WriteByte(0xFF);

            diskContent = sourceStream;
        }
Exemple #27
0
        public void CreateByCylinder()
        {
            SparseMemoryStream ms   = new SparseMemoryStream();
            Geometry           geom = new Geometry(15, 30, 63);

            ms.SetLength(geom.Capacity);
            BiosPartitionTable table = BiosPartitionTable.Initialize(ms, geom);

            Assert.AreEqual(0, table.CreatePrimaryByCylinder(0, 4, 33, false));
            Assert.AreEqual(1, table.CreatePrimaryByCylinder(10, 14, 33, false));

            Assert.AreEqual(geom.ToLogicalBlockAddress(new ChsAddress(0, 1, 1)), table[0].FirstSector);
            Assert.AreEqual(geom.ToLogicalBlockAddress(new ChsAddress(5, 0, 1)) - 1, table[0].LastSector);
            Assert.AreEqual(geom.ToLogicalBlockAddress(new ChsAddress(10, 0, 1)), table[1].FirstSector);
            Assert.AreEqual(geom.ToLogicalBlockAddress(new ChsAddress(14, 29, 63)), table[1].LastSector);
        }
Exemple #28
0
        public void ExtentInfo()
        {
            using (SparseMemoryStream ms = new SparseMemoryStream())
            {
                Geometry       diskGeometry = Geometry.FromCapacity(30 * 1024 * 1024);
                NtfsFileSystem ntfs         = NtfsFileSystem.Format(ms, "", diskGeometry, 0, diskGeometry.TotalSectorsLong);

                // Check non-resident attribute
                using (Stream s = ntfs.OpenFile(@"file", FileMode.Create, FileAccess.ReadWrite))
                {
                    byte[] data = new byte[(int)ntfs.ClusterSize];
                    data[0] = 0xAE;
                    data[1] = 0x3F;
                    data[2] = 0x8D;
                    s.Write(data, 0, (int)ntfs.ClusterSize);
                }

                var extents = ntfs.PathToExtents("file");
                Assert.Equal(1, extents.Length);
                Assert.Equal(ntfs.ClusterSize, extents[0].Length);

                ms.Position = extents[0].Start;
                Assert.Equal(0xAE, ms.ReadByte());
                Assert.Equal(0x3F, ms.ReadByte());
                Assert.Equal(0x8D, ms.ReadByte());


                // Check resident attribute
                using (Stream s = ntfs.OpenFile(@"file2", FileMode.Create, FileAccess.ReadWrite))
                {
                    s.WriteByte(0xBA);
                    s.WriteByte(0x82);
                    s.WriteByte(0x2C);
                }
                extents = ntfs.PathToExtents("file2");
                Assert.Equal(1, extents.Length);
                Assert.Equal(3, extents[0].Length);

                byte[] read = new byte[100];
                ms.Position = extents[0].Start;
                ms.Read(read, 0, 100);

                Assert.Equal(0xBA, read[0]);
                Assert.Equal(0x82, read[1]);
                Assert.Equal(0x2C, read[2]);
            }
        }
        public BiosPartitionedDiskBuilder(long capacity, byte[] bootSectors, Geometry biosGeometry)
        {
            if (bootSectors == null)
            {
                throw new ArgumentNullException(nameof(bootSectors));
            }

            _capacity     = capacity;
            _biosGeometry = biosGeometry;

            _bootSectors = new SparseMemoryStream();
            _bootSectors.SetLength(capacity);
            _bootSectors.Write(bootSectors, 0, bootSectors.Length);
            PartitionTable = new BiosPartitionTable(_bootSectors, biosGeometry);

            _partitionContents = new Dictionary <int, BuilderExtent>();
        }
Exemple #30
0
        public void V8Container_Constructor_ThrowsIfOnIncorrectStream(
            V8ContainerMode mode, bool canSeek, bool canRead, bool canWrite, string expectedMessage)
        {
            using (var baseStream = new SparseMemoryStream(canRead, canWrite, canSeek))
            {
                Action ctor = () =>
                {
                    using (new V8Container(baseStream, mode))
                    {
                    }
                };

                ctor.Should()
                .Throw <ArgumentException>()
                .WithMessage(expectedMessage);
            }
        }
        public void Seek()
        {
            SparseMemoryStream memStream = new SparseMemoryStream(new SparseMemoryBuffer(1), FileAccess.ReadWrite);

            memStream.SetLength(1024);

            ThreadSafeStream tss = new ThreadSafeStream(memStream);

            tss.Seek(10, SeekOrigin.Begin);
            Assert.Equal(10, tss.Position);

            tss.Seek(10, SeekOrigin.Current);
            Assert.Equal(20, tss.Position);

            tss.Seek(-10, SeekOrigin.End);
            Assert.Equal(1014, tss.Position);
        }
        public void CreateBySize()
        {
            long capacity = 3 * 1024 * 1024;
            SparseMemoryStream ms = new SparseMemoryStream();
            ms.SetLength(capacity);
            Geometry geom = Geometry.FromCapacity(capacity);
            BiosPartitionTable table = BiosPartitionTable.Initialize(ms, geom);

            int idx = table.Create(2 * 1024 * 1024, WellKnownPartitionType.WindowsFat, false);

            // Make sure the partition is within 10% of the size requested.
            Assert.That((2 * 1024 * 2) * 0.9 < table[idx].SectorCount);

            Assert.AreEqual(geom.ToLogicalBlockAddress(new ChsAddress(0, 1, 1)), table[idx].FirstSector);
            Assert.AreEqual(geom.HeadsPerCylinder - 1, geom.ToChsAddress((int)table[idx].LastSector).Head);
            Assert.AreEqual(geom.SectorsPerTrack, geom.ToChsAddress((int)table[idx].LastSector).Sector);
        }
        public void DisposeView()
        {
            SparseMemoryStream memStream = new SparseMemoryStream(new SparseMemoryBuffer(1), FileAccess.ReadWrite);

            memStream.SetLength(1024);

            ThreadSafeStream tss = new ThreadSafeStream(memStream);

            SparseStream altView = tss.OpenView();

            altView.Dispose();

            tss.ReadByte();

            SparseStream altView2 = tss.OpenView();

            altView2.ReadByte();
        }
        public void FieldUpdating(PXCache sender, PXFieldUpdatingEventArgs e)
        {
            if (e.NewValue != null)
            {
                if (e.NewValue is byte[][])
                {
                    return;
                }

                var fileStream = new SparseMemoryStream();
                var gZipStream = new GZipStream(fileStream, CompressionMode.Compress);
                PXReflectionSerializer.Serialize(gZipStream, e.NewValue, false);

                gZipStream.Close();
                fileStream.Close();
                e.NewValue = fileStream.GetBuf();
            }
        }
Exemple #35
0
        public void CreateBySize()
        {
            long capacity         = 3 * 1024 * 1024;
            SparseMemoryStream ms = new SparseMemoryStream();

            ms.SetLength(capacity);
            Geometry           geom  = Geometry.FromCapacity(capacity);
            BiosPartitionTable table = BiosPartitionTable.Initialize(ms, geom);

            int idx = table.Create(2 * 1024 * 1024, WellKnownPartitionType.WindowsFat, false);

            // Make sure the partition is within 10% of the size requested.
            Assert.That((2 * 1024 * 2) * 0.9 < table[idx].SectorCount);

            Assert.AreEqual(geom.ToLogicalBlockAddress(new ChsAddress(0, 1, 1)), table[idx].FirstSector);
            Assert.AreEqual(geom.HeadsPerCylinder - 1, geom.ToChsAddress((int)table[idx].LastSector).Head);
            Assert.AreEqual(geom.SectorsPerTrack, geom.ToChsAddress((int)table[idx].LastSector).Sector);
        }
        /// <summary>
        /// Find offset of next available block after this offset
        /// </summary>
        /// <param name="cache">cache to inspect</param>
        /// <param name="start">offset to start search from</param>
        /// <returns>offset of block start if found, otherwise -1</returns>
        /// <remarks>Contract: Call only when start is not inside any existing block.</remarks>
        private long FindOffsetOfNextAvailableBlockAfter(SparseMemoryStream cache, long start)
        {
            Debug.Assert(start >= 0);
            Debug.Assert(cache != null);

            // Find the index where a new block with offset start would be placed
            bool match;
            int index = FindIndexOfBlockAtOffset(cache, start, out match);
            Debug.Assert(!match, "Must only be called when there is no match");

            // If we have an exact match, we return the offset of the next block, unless
            // there are no more blocks - then we return -1
            if (index >= (cache.MemoryBlockCollection.Count))
                return -1;      // no block beyond start
            else
            {
                return cache.MemoryBlockCollection[index].Offset;
            }
        }
        /// <summary>
        /// Uses BinarySearch to locate the index of the block that contains start
        /// </summary>
        /// <param name="cache"></param>
        /// <param name="start"></param>
        /// <param name="match">True if match found.  If this is false, the index returned is where the item would appear if it existed.</param>
        /// <returns>Index</returns>
        private int FindIndexOfBlockAtOffset(SparseMemoryStream cache, long start, out bool match)
        {
            if (cache.MemoryBlockCollection.Count == 0)
            {
                match = false;
                return 0;
            }

            // use BinarySearch to locate blocks of interest quickly
            if (_comparisonBlock == null)
                _comparisonBlock = new MemoryStreamBlock(null, start);
            else
                _comparisonBlock.Offset = start;

            int index = cache.MemoryBlockCollection.BinarySearch(_comparisonBlock);
            if (index < 0) // no match
            {
                // ~index represents the place at which the block we asked for
                // would appear if it existed
                index = ~index;
                match = false;
            }
            else
            {
                match = true;
            }
            return index;
        }
        private int ReadFromCache(SparseMemoryStream cache, long start, int count, byte[] buffer, int bufferOffset)
        {
#if DEBUG        
            // debug only check for valid parameters, as we generally expect callers to verify them 
            PackagingUtilities.VerifyStreamReadArgs(this, buffer, bufferOffset, count);
#endif
            Debug.Assert(cache != null);
            Debug.Assert(start >=0);
            IList<MemoryStreamBlock> collection = cache.MemoryBlockCollection;

            checked
            {
                // use BinarySearch to locate blocks of interest quickly
                bool match;     // exact match?
                int index = FindIndexOfBlockAtOffset(cache, start, out match);

                // if match was found, read from it
                int bytesRead = 0;
                if (match)
                {
                    MemoryStreamBlock memStreamBlock = collection[index];
                    long overlapBlockOffset;
                    long overlapBlockSize;
                    
                    // we have got an overlap which can be used to satisfy the read request,
                    // at least  partially
                    PackagingUtilities.CalculateOverlap(memStreamBlock.Offset, memStreamBlock.Stream.Length,
                                          start, count,
                                          out overlapBlockOffset, out overlapBlockSize);

                    if (overlapBlockSize > 0)
                    {
                        // overlap must be starting at the start as we know for sure that 
                        // memStreamBlock.Offset <= start
                        Debug.Assert(overlapBlockOffset == start); 

                        memStreamBlock.Stream.Seek(overlapBlockOffset - memStreamBlock.Offset, SeekOrigin.Begin);

                        // we know that memStream will return as much data as we requested
                        // even if this logic changes we do not have to return everything 
                        // a partially complete read is acceptable here 
                        bytesRead = memStreamBlock.Stream.Read(buffer, bufferOffset, (int)overlapBlockSize);
                    }
                }

                return bytesRead;
            }
        }
        public void Initialize()
        {
            long capacity = 3 * 1024 * 1024;
            SparseMemoryStream ms = new SparseMemoryStream();
            ms.SetLength(capacity);
            Geometry geom = Geometry.FromCapacity(capacity);
            BiosPartitionTable table = BiosPartitionTable.Initialize(ms, geom);

            Assert.AreEqual(0, table.Count);
        }
        public void CreateWholeDiskAligned()
        {
            long capacity = 3 * 1024 * 1024;
            SparseMemoryStream ms = new SparseMemoryStream();
            ms.SetLength(capacity);
            Geometry geom = Geometry.FromCapacity(capacity);
            BiosPartitionTable table = BiosPartitionTable.Initialize(ms, geom);

            int idx = table.CreateAligned(WellKnownPartitionType.WindowsFat, true, 64 * 1024);

            Assert.AreEqual(0, table[idx].FirstSector % 128);
            Assert.AreEqual(0, (table[idx].LastSector + 1) % 128);
            Assert.Greater(table[idx].SectorCount * 512, capacity * 0.9);

            // Make sure the partition index is Zero
            Assert.AreEqual(0, ((BiosPartitionInfo)table[idx]).PrimaryIndex);
        }
Exemple #41
0
        public override void SetLength(long newLength)
        {
            CheckDisposed(); 

            Debug.Assert(_cachePrefixStream == null); // we only expect this thing to be not null during Archive Save execution
                                                                                // that would between PreSaveNotofication call and Save SaveStreaming
                
            if (newLength < 0)
            {
                throw new ArgumentOutOfRangeException("newLength");
            }

            if (_currentStreamLength != newLength)
            {
                _dirtyFlag = true;
                _dataChanged = true;

                if  (newLength <= _persistedSize)
                {
                    // the stream becomes smaller than our disk block, which means that  
                    // we can drop the in-memory-sparse-suffix 
                    if (_sparseMemoryStreamSuffix  != null)
                    {
                        _sparseMemoryStreamSuffix.Close();
                        _sparseMemoryStreamSuffix  = null;                
                    }
                }
                else
                {
                    // we need to construct Sparse Memory stream if we do not have one yet 
                    if (_sparseMemoryStreamSuffix  == null)
                    {
                        _sparseMemoryStreamSuffix  = new SparseMemoryStream(_lowWaterMark, _highWaterMark);
                    }

                    // set size on the Sparse Memory Stream 
                    _sparseMemoryStreamSuffix.SetLength(newLength - _persistedSize); // no need for checked as it was verified above 
                }

                _currentStreamLength = newLength;

                // if stream was truncated to the point that our current position is beyond the end of the stream,
                // we need to reset position so it is at the end of the stream 
                if (_currentStreamLength < _currentStreamPosition)
                    Seek(_currentStreamLength, SeekOrigin.Begin);
            }
        }
        public void Format_LargeDisk()
        {
            long size = 1024L * 1024 * 1024L * 1024; // 1 TB
            SparseMemoryStream partStream = new SparseMemoryStream();
            NtfsFileSystem.Format(partStream, "New Partition", Geometry.FromCapacity(size), 0, size / 512);

            NtfsFileSystem ntfs = new NtfsFileSystem(partStream);
            ntfs.Dump(TextWriter.Null, "");
        }
Exemple #43
0
        IDataTransform.GetTransformedStream(
            Stream encodedStream,
            IDictionary transformContext
            )
        {
            Stream tempStream = new SparseMemoryStream(_lowWaterMark, _highWaterMark);
            tempStream = new CompressEmulationStream(encodedStream, tempStream, 0, new CompoundFileDeflateTransform());

            // return a VersionedStream that works with the VersionedStreamOwner
            // to verify/update our FormatVersion info
            return new VersionedStream(tempStream, _versionedStreamOwner);
        }
        public void CreateBySizeInGapAligned()
        {
            SparseMemoryStream ms = new SparseMemoryStream();
            Geometry geom = new Geometry(15, 30, 63);
            ms.SetLength(geom.Capacity);
            BiosPartitionTable table = BiosPartitionTable.Initialize(ms, geom);

            Assert.AreEqual(0, table.CreatePrimaryByCylinder(0, 4, 33, false));
            Assert.AreEqual(1, table.CreatePrimaryByCylinder(10, 14, 33, false));

            int idx = table.CreateAligned(3 * 1024 * 1024, WellKnownPartitionType.WindowsFat, true, 64 * 1024);
            Assert.AreEqual(2, idx);

            Assert.AreEqual(0, table[idx].FirstSector % 128);
            Assert.AreEqual(0, (table[idx].LastSector + 1) % 128);
        }
Exemple #45
0
        /// <summary>
        /// Write
        /// </summary>
        /// <param name="buffer"></param>
        /// <param name="offset"></param>
        /// <param name="count"></param>
        /// <remarks>In streaming mode, write should accumulate data into the SparseMemoryStream.</remarks>
        override public void Write(byte[] buffer, int offset, int count)
        {
            CheckDisposed();   

            PackagingUtilities.VerifyStreamWriteArgs(this, buffer, offset, count);

            Debug.Assert(_cachePrefixStream == null); // we only expect this thing to be not null during Archive Save execution
                                                      // that would between PreSaveNotofication call and Save SaveStreaming

            Debug.Assert(_currentStreamPosition >= 0);

            if (count == 0)
            {
                return; 
            }
        
            int diskBytesToWrite = 0;
    
            _dirtyFlag = true;
            _dataChanged = true;
            long newStreamPosition = _currentStreamPosition;
            checked
            {
                // Try to satisfy request with the Write to the Disk 
                if  (newStreamPosition  < _persistedSize)
                {
                    Debug.Assert(!_blockManager.Streaming);

                    // we have at least partial overlap between request and the data on disk 
                    _blockManager.Stream.Seek(_persistedOffset + newStreamPosition, SeekOrigin.Begin);
                    // Note on casting:
                    //  It is safe to cast the result of Math.Min(count, _persistedSize - newStreamPosition))
                    //      from long to int since it cannot be bigger than count and count is int type
                    diskBytesToWrite = (int) (Math.Min(count, _persistedSize - newStreamPosition));  // this is a safe cast as count has int type 

                    _blockManager.Stream.Write(buffer, offset, diskBytesToWrite);
                    newStreamPosition += diskBytesToWrite;
                    count -= diskBytesToWrite;
                    offset += diskBytesToWrite;
                }

                // check whether we need to save data to the memory Stream;
                if  (newStreamPosition + count > _persistedSize)
                {
                    if (_sparseMemoryStreamSuffix  == null)
                    {
                         _sparseMemoryStreamSuffix  = new SparseMemoryStream(_lowWaterMark, _highWaterMark);
                    }
                    
                    _sparseMemoryStreamSuffix.Seek(newStreamPosition - _persistedSize, SeekOrigin.Begin);

                    _sparseMemoryStreamSuffix.Write(buffer, offset, count);
                    newStreamPosition += count;
                }

                _currentStreamPosition = newStreamPosition;
                _currentStreamLength = Math.Max(_currentStreamLength, _currentStreamPosition);                                 
            }
            return;
        }
        public void LargeDisk()
        {
            long capacity = 300 * 1024L * 1024L * 1024;
            SparseMemoryStream ms = new SparseMemoryStream();
            ms.SetLength(capacity);
            Geometry geom = Geometry.LbaAssistedBiosGeometry(capacity);
            BiosPartitionTable table = BiosPartitionTable.Initialize(ms, geom);

            table.Create(150 * 1024L * 1024L * 1024, WellKnownPartitionType.WindowsNtfs, false);
            table.Create(20 * 1024L * 1024L * 1024, WellKnownPartitionType.WindowsNtfs, false);
            table.Create(20 * 1024L * 1024L * 1024, WellKnownPartitionType.WindowsNtfs, false);

            Assert.AreEqual(3, table.Partitions.Count);
            Assert.Greater(table[0].SectorCount * 512L, 140 * 1024L * 1024L * 1024);
            Assert.Greater(table[1].SectorCount * 512L, 19 * 1024L * 1024L * 1024);
            Assert.Greater(table[2].SectorCount * 512L, 19 * 1024L * 1024L * 1024);

            Assert.Greater(table[0].FirstSector, 0);
            Assert.Greater(table[1].FirstSector, table[0].LastSector);
            Assert.Greater(table[2].FirstSector, table[1].LastSector);
        }
        public void HonoursReadOnly()
        {
            SparseMemoryStream diskStream = new SparseMemoryStream();
            FatFileSystem fs = FatFileSystem.FormatFloppy(diskStream, FloppyDiskType.HighDensity, "FLOPPY_IMG ");

            fs.CreateDirectory(@"AAA");
            fs.CreateDirectory(@"BAR");
            using (Stream t = fs.OpenFile(@"BAR\AAA.TXT", FileMode.Create, FileAccess.ReadWrite)) { }
            using (Stream s = fs.OpenFile(@"BAR\FOO.TXT", FileMode.Create, FileAccess.ReadWrite))
            {
                StreamWriter w = new StreamWriter(s);
                w.WriteLine("FOO - some sample text");
                w.Flush();
            }
            fs.SetLastAccessTimeUtc(@"BAR", new DateTime(1980, 1, 1));
            fs.SetLastAccessTimeUtc(@"BAR\FOO.TXT", new DateTime(1980, 1, 1));

            // Check we can access a file without any errors
            SparseStream roDiskStream = SparseStream.ReadOnly(diskStream, Ownership.None);
            FatFileSystem fatFs = new FatFileSystem(roDiskStream);
            using (Stream fileStream = fatFs.OpenFile(@"BAR\FOO.TXT", FileMode.Open))
            {
                fileStream.ReadByte();
            }
        }
        public void ExtentInfo()
        {
            using (SparseMemoryStream ms = new SparseMemoryStream())
            {
                Geometry diskGeometry = Geometry.FromCapacity(30 * 1024 * 1024);
                NtfsFileSystem ntfs = NtfsFileSystem.Format(ms, "", diskGeometry, 0, diskGeometry.TotalSectors);

                // Check non-resident attribute
                using (Stream s = ntfs.OpenFile(@"file", FileMode.Create, FileAccess.ReadWrite))
                {
                    byte[] data = new byte[(int)ntfs.ClusterSize];
                    data[0] = 0xAE;
                    data[1] = 0x3F;
                    data[2] = 0x8D;
                    s.Write(data, 0, (int)ntfs.ClusterSize);
                }

                var extents = ntfs.PathToExtents("file");
                Assert.AreEqual(1, extents.Length);
                Assert.AreEqual(ntfs.ClusterSize, extents[0].Length);

                ms.Position = extents[0].Start;
                Assert.AreEqual(0xAE, ms.ReadByte());
                Assert.AreEqual(0x3F, ms.ReadByte());
                Assert.AreEqual(0x8D, ms.ReadByte());

                // Check resident attribute
                using (Stream s = ntfs.OpenFile(@"file2", FileMode.Create, FileAccess.ReadWrite))
                {
                    s.WriteByte(0xBA);
                    s.WriteByte(0x82);
                    s.WriteByte(0x2C);
                }
                extents = ntfs.PathToExtents("file2");
                Assert.AreEqual(1, extents.Length);
                Assert.AreEqual(3, extents[0].Length);

                byte[] read = new byte[100];
                ms.Position = extents[0].Start;
                ms.Read(read, 0, 100);

                Assert.AreEqual(0xBA, read[0]);
                Assert.AreEqual(0x82, read[1]);
                Assert.AreEqual(0x2C, read[2]);
            }
        }
        public void VeryLargePartition()
        {
            long capacity = 1300 * 1024L * 1024L * 1024;
            SparseMemoryStream ms = new SparseMemoryStream();
            ms.SetLength(capacity);
            Geometry geom = Geometry.LbaAssistedBiosGeometry(capacity);
            BiosPartitionTable table = BiosPartitionTable.Initialize(ms, geom);

            // exception occurs here
            int i = table.CreatePrimaryByCylinder(0, 150000, (byte)WellKnownPartitionType.WindowsNtfs, true);

            Assert.AreEqual(150000, geom.ToChsAddress(table[0].LastSector).Cylinder);
        }
        public void Format_SmallDisk()
        {
            long size = 8 * 1024 * 1024;
            SparseMemoryStream partStream = new SparseMemoryStream();
            //VirtualDisk disk = Vhd.Disk.InitializeDynamic(partStream, Ownership.Dispose, size);
            NtfsFileSystem.Format(partStream, "New Partition", Geometry.FromCapacity(size), 0, size / 512);

            NtfsFileSystem ntfs = new NtfsFileSystem(partStream);
            ntfs.Dump(TextWriter.Null, "");
        }
        /// <summary>
        /// This is the common Pre Save notiofication handler for 
        ///  RawDataFile Block and File Item Stream
        /// It makes assumption that the overlap generally start coming in at the beginning of a 
        /// large disk image, so we should only try to cache cache overlaped data in the prefix 
        /// of the disk block
        /// Block can also return a value indicating whether PreSaveNotification should be extended to the blocks that are positioned after 
        /// it in the Block List. For example, if block has completely handled PreSaveNotification in a way that it cached the whole area that
        /// was in danger (of being overwritten) it means that no blocks need to worry about this anymore. After all no 2 blocks should have
        /// share on disk buffers. Another scenario is when block can determine that area in danger is positioned before the block's on disk
        /// buffers; this means that all blocks that are positioned later in the block list do not need to worry about this PreSaveNotification 
        /// as their buffers should be positioned even further alone in the file.
        /// </summary> 
        internal static PreSaveNotificationScanControlInstruction CommonPreSaveNotificationHandler( 
                                                            Stream stream,
                                                            long offset, long size, 
                                                            long onDiskOffset, long onDiskSize,
                                                            ref SparseMemoryStream cachePrefixStream)
        {
            checked 
            {
                Debug.Assert(size >=0); 
                Debug.Assert(offset >=0); 
                Debug.Assert(onDiskSize >=0);
                Debug.Assert(onDiskOffset >=0); 

                // trivial request
                if (size == 0)
                { 
                    // The area being overwritten is of size 0 so there is no need to notify any blocks about this.
                    return PreSaveNotificationScanControlInstruction.Stop; 
                } 

                if (cachePrefixStream != null) 
                {
                    // if we have something in cache prefix buffer  we only should check whatever tail data isn't cached
                    checked{onDiskOffset += cachePrefixStream.Length;}
                    checked{onDiskSize -= cachePrefixStream.Length;} 
                    Debug.Assert(onDiskSize >=0);
                } 
 
                if (onDiskSize == 0)
                { 
                    // the raw data block happened to be fully cached
                    // in this case (onDiskSize==0) can not be used as a reliable indicator of the position of the
                    // on disk buffer relative to the other; it is just an indicator of an empty buffer which might have a meaningless offset
                    // that shouldn't be driving any decisions 
                    return PreSaveNotificationScanControlInstruction.Continue;
                } 
 
                // we need to first find out if the raw data that isn't cached yet overlaps with any disk space
                // that is about to be overriden 
                long overlapBlockOffset;
                long  overlapBlockSize;

                PackagingUtilities.CalculateOverlap(onDiskOffset, onDiskSize, 
                                           offset, size ,
                                            out overlapBlockOffset, out overlapBlockSize); 
                if (overlapBlockSize <= 0) 
                {
                    // No overlap , we can ignore this message. 
                    // In addition to that, if (onDiskOffset > offset) it means that, given the fact that all blocks after
                    // the current one will have even larger offsets, they couldn't possibly overlap with (offset ,size ) chunk .
                    return (onDiskOffset > offset) ?
                                                PreSaveNotificationScanControlInstruction.Stop  : 
                                                PreSaveNotificationScanControlInstruction.Continue;
                } 
 
                // at this point we have an overlap, we need to read the data that is overlapped
                // and merge it with whatever we already have in cache 
                // let's figure out the part that isn't cached yet, and needs to be
                long blockSizeToCache;
                checked
                { 
                    blockSizeToCache = overlapBlockOffset + overlapBlockSize - onDiskOffset;
                } 
                Debug.Assert(blockSizeToCache >0); // there must be a non empty block at this point that needs to be cached 

                // We need to ensure that we do have a place to store this data 
                if (cachePrefixStream == null)
                {
                    cachePrefixStream = new SparseMemoryStream(_lowWaterMark, _highWaterMark);
                } 
                else
                { 
                    // if we already have some cached prefix data we have to make sure we are 
                    // appending new data tro the tail of the already cached chunk
                    cachePrefixStream.Seek(0, SeekOrigin.End); 
                }

                stream.Seek(onDiskOffset, SeekOrigin.Begin);
                long bytesCopied = PackagingUtilities.CopyStream(stream, cachePrefixStream, blockSizeToCache, 4096); 

                if (bytesCopied  != blockSizeToCache) 
                { 
                    throw new FileFormatException(SR.Get(SRID.CorruptedData));
                } 

                // if the contdition below is true it means that, given the fact that all blocks after
                // the current one will have even larger offsets, they couldn't possibly overlap with (offset ,size ) chunk
                return ((onDiskOffset + onDiskSize) >=  (offset + size)) ? 
                                            PreSaveNotificationScanControlInstruction.Stop  :
                                            PreSaveNotificationScanControlInstruction.Continue; 
            } 
        }
Exemple #52
0
        public void Setup()
        {
            SparseMemoryStream sourceStream = new SparseMemoryStream();
            sourceStream.SetLength(160 * 1024L * 1024);
            for (int i = 0; i < 8; ++i)
            {
                sourceStream.Position = i * 1024L * 1024;
                sourceStream.WriteByte((byte)i);
            }

            sourceStream.Position = 150 * 1024 * 1024;
            sourceStream.WriteByte(0xFF);

            diskContent = sourceStream;
        }
        public void CreateWholeDisk()
        {
            long capacity = 3 * 1024 * 1024;
            SparseMemoryStream ms = new SparseMemoryStream();
            ms.SetLength(capacity);
            Geometry geom = Geometry.FromCapacity(capacity);
            BiosPartitionTable table = BiosPartitionTable.Initialize(ms, geom);

            int idx = table.Create(WellKnownPartitionType.WindowsFat, true);

            // Make sure the partition fills all but the first track on the disk.
            Assert.AreEqual(geom.TotalSectors, table[idx].SectorCount + geom.SectorsPerTrack);

            // Make sure FAT16 was selected for a disk of this size
            Assert.AreEqual(BiosPartitionTypes.Fat16, table[idx].BiosType);

            // Make sure partition starts where expected
            Assert.AreEqual(new ChsAddress(0, 1, 1), ((BiosPartitionInfo)table[idx]).Start);

            // Make sure partition ends at end of disk
            Assert.AreEqual(geom.ToLogicalBlockAddress(geom.LastSector), table[idx].LastSector);
            Assert.AreEqual(geom.LastSector, ((BiosPartitionInfo)table[idx]).End);

            // Make sure the 'active' flag made it through...
            Assert.IsTrue(((BiosPartitionInfo)table[idx]).IsActive);

            // Make sure the partition index is Zero
            Assert.AreEqual(0, ((BiosPartitionInfo)table[idx]).PrimaryIndex);
        }
        /// <summary>
        /// Initializes a new instance of the BiosPartitionedDiskBuilder class by
        /// cloning the partition structure of a source disk.
        /// </summary>
        /// <param name="sourceDisk">The disk to clone</param>
        public BiosPartitionedDiskBuilder(VirtualDisk sourceDisk)
        {
            _capacity = sourceDisk.Capacity;
            _biosGeometry = sourceDisk.BiosGeometry;

            _bootSectors = new SparseMemoryStream();
            _bootSectors.SetLength(_capacity);

            foreach (var extent in new BiosPartitionTable(sourceDisk).GetMetadataDiskExtents())
            {
                sourceDisk.Content.Position = extent.Start;
                byte[] buffer = Utilities.ReadFully(sourceDisk.Content, (int)extent.Length);
                _bootSectors.Position = extent.Start;
                _bootSectors.Write(buffer, 0, buffer.Length);
            }

            _partitionTable = new BiosPartitionTable(_bootSectors, _biosGeometry);

            _partitionContents = new Dictionary<int, BuilderExtent>();
        }
Exemple #55
0
        /// <summary> 
        /// ChangeMode 
        /// </summary>
        /// <param name="newMode"></param> 
        /// <remarks>Does not update Position of _current for change to ReadPassThroughMode.</remarks>
        private void ChangeMode(Mode newMode)
        {
            // ignore redundant calls (allowing these actually simplifies the logic in SetLength) 
            if (newMode == _mode)
                return; 
 
            // every state change requires this logic
            if (_current != null) 
            {
                _current.Close();
                _dirtyForClosing = false;
                _dirtyForFlushing = false; 
            }
 
            // set the new mode - must be done before the call to Seek 
            _mode = newMode;
 
            switch (newMode)
            {
                case Mode.Start:
                    { 
                        _current = null;
                        _baseStream.Position = 0; 
                        break; 
                    }
 
                case Mode.ReadPassThrough:
                case Mode.WritePassThrough:
                    {
                        Debug.Assert(_baseStream.Position == 0); 

                        // create the appropriate DeflateStream 
                        _current = new DeflateStream(_baseStream, 
                            newMode == Mode.WritePassThrough ? CompressionMode.Compress : CompressionMode.Decompress,
                            true); 

                        break;
                    }
                case Mode.Emulation: 
                    {
                        // Create emulation stream.  Use a MemoryStream for local caching. 
                        // Do not change this logic for RM cases because the data is "in the clear" and must 
                        // not be persisted in a vulnerable location.
 
                        SparseMemoryStream memStream = new SparseMemoryStream(_lowWaterMark, _highWaterMark);
                        _current = new CompressEmulationStream(_baseStream, memStream, _position, new DeflateEmulationTransform());

                        // verify and set length 
                        UpdateUncompressedDataLength(_current.Length);
                        break; 
                    } 
                case Mode.Disposed: break;
                default: 
                    Debug.Assert(false, "Illegal state for CompressStream - logic error"); break;
            }
        }
        public void SetActive()
        {
            long capacity = 10 * 1024 * 1024;
            SparseMemoryStream ms = new SparseMemoryStream();
            ms.SetLength(capacity);
            Geometry geom = Geometry.FromCapacity(capacity);
            BiosPartitionTable table = BiosPartitionTable.Initialize(ms, geom);

            table.Create(1 * 1024 * 1024, WellKnownPartitionType.WindowsFat, false);
            table.Create(2 * 1024 * 1024, WellKnownPartitionType.WindowsFat, false);
            table.Create(3 * 1024 * 1024, WellKnownPartitionType.WindowsFat, false);

            table.SetActivePartition(1);
            table.SetActivePartition(2);
            Assert.IsFalse(((BiosPartitionInfo)table.Partitions[1]).IsActive);
            Assert.IsTrue(((BiosPartitionInfo)table.Partitions[2]).IsActive);
        }
        public void Delete()
        {
            long capacity = 10 * 1024 * 1024;
            SparseMemoryStream ms = new SparseMemoryStream();
            ms.SetLength(capacity);
            Geometry geom = Geometry.FromCapacity(capacity);
            BiosPartitionTable table = BiosPartitionTable.Initialize(ms, geom);

            Assert.AreEqual(0, table.Create(1 * 1024 * 1024, WellKnownPartitionType.WindowsFat, false));
            Assert.AreEqual(1, table.Create(2 * 1024 * 1024, WellKnownPartitionType.WindowsFat, false));
            Assert.AreEqual(2, table.Create(3 * 1024 * 1024, WellKnownPartitionType.WindowsFat, false));

            long[] sectorCount = new long[] { table[0].SectorCount, table[1].SectorCount, table[2].SectorCount };

            table.Delete(1);

            Assert.AreEqual(2, table.Count);
            Assert.AreEqual(sectorCount[2], table[1].SectorCount);
        }