private static long CalcSize(SparseStream content, ServerSparseExtentHeader header)
            {
                long numDataGrains     = StreamExtent.BlockCount(content.Extents, header.GrainSize * Sizes.Sector);
                long grainTableSectors = Utilities.Ceil(header.NumGTEsPerGT * 4, Sizes.Sector);

                return((grainTableSectors + (numDataGrains * header.GrainSize)) * Sizes.Sector);
            }
        internal override List <BuilderExtent> FixExtents(out long totalLength)
        {
            List <BuilderExtent> extents = new List <BuilderExtent>();

            ServerSparseExtentHeader header   = DiskImageFile.CreateServerSparseExtentHeader(_content.Length);
            GlobalDirectoryExtent    gdExtent = new GlobalDirectoryExtent(header);

            long grainTableStart    = (header.GdOffset * Sizes.Sector) + gdExtent.Length;
            long grainTableCoverage = header.NumGTEsPerGT * header.GrainSize * Sizes.Sector;

            foreach (var grainTableRange in StreamExtent.Blocks(_content.Extents, grainTableCoverage))
            {
                for (int i = 0; i < grainTableRange.Count; ++i)
                {
                    long             grainTable = grainTableRange.Offset + i;
                    long             dataStart  = grainTable * grainTableCoverage;
                    GrainTableExtent gtExtent   = new GrainTableExtent(grainTableStart, new SubStream(_content, dataStart, Math.Min(grainTableCoverage, _content.Length - dataStart)), header);
                    extents.Add(gtExtent);
                    gdExtent.SetEntry((int)grainTable, (uint)(grainTableStart / Sizes.Sector));

                    grainTableStart += gtExtent.Length;
                }
            }

            extents.Insert(0, gdExtent);

            header.FreeSector = (uint)(grainTableStart / Sizes.Sector);

            byte[] buffer = header.GetBytes();
            extents.Insert(0, new BuilderBufferExtent(0, buffer));

            totalLength = grainTableStart;

            return(extents);
        }
Exemple #3
0
        private static void CreateExtent(Stream extentStream, long size, ExtentType type, long descriptorLength, out long descriptorStart)
        {
            if (type == ExtentType.Flat || type == ExtentType.Vmfs)
            {
                extentStream.SetLength(size);
                descriptorStart = 0;
                return;
            }

            if (type == ExtentType.Sparse)
            {
                CreateSparseExtent(extentStream, size, descriptorLength, out descriptorStart);
                return;
            }
            else if (type == ExtentType.VmfsSparse)
            {
                ServerSparseExtentHeader header = CreateServerSparseExtentHeader(size);

                extentStream.Position = 0;
                extentStream.Write(header.GetBytes(), 0, 4 * Sizes.Sector);

                byte[] blankGlobalDirectory = new byte[header.NumGdEntries * 4];
                extentStream.Write(blankGlobalDirectory, 0, blankGlobalDirectory.Length);

                descriptorStart = 0;
                return;
            }
            else
            {
                throw new NotImplementedException("Extent type not implemented");
            }
        }
Exemple #4
0
        internal static ServerSparseExtentHeader CreateServerSparseExtentHeader(long size)
        {
            uint numSectors   = (uint)Utilities.Ceil(size, Sizes.Sector);
            uint numGDEntries = (uint)Utilities.Ceil(numSectors * (long)Sizes.Sector, 2 * Sizes.OneMiB);

            ServerSparseExtentHeader header = new ServerSparseExtentHeader();

            header.Capacity     = numSectors;
            header.GrainSize    = 1;
            header.GdOffset     = 4;
            header.NumGdEntries = numGDEntries;
            header.FreeSector   = (uint)(header.GdOffset + Utilities.Ceil(numGDEntries * 4, Sizes.Sector));
            return(header);
        }
Exemple #5
0
        public ServerSparseExtentStream(Stream file, Ownership ownsFile, long diskOffset, SparseStream parentDiskStream, Ownership ownsParentDiskStream)
        {
            _fileStream           = file;
            _ownsFileStream       = ownsFile;
            _diskOffset           = diskOffset;
            _parentDiskStream     = parentDiskStream;
            _ownsParentDiskStream = ownsParentDiskStream;

            file.Position = 0;
            byte[] firstSectors = Utilities.ReadFully(file, Sizes.Sector * 4);
            _serverHeader = ServerSparseExtentHeader.Read(firstSectors, 0);
            _header       = _serverHeader;

            _gtCoverage = _header.NumGTEsPerGT * (long)_header.GrainSize * Sizes.Sector;

            LoadGlobalDirectory();
        }
Exemple #6
0
        public static ServerSparseExtentHeader Read(byte[] buffer, int offset)
        {
            ServerSparseExtentHeader hdr = new ServerSparseExtentHeader();

            hdr.MagicNumber  = Utilities.ToUInt32LittleEndian(buffer, offset + 0x00);
            hdr.Version      = Utilities.ToUInt32LittleEndian(buffer, offset + 0x04);
            hdr.Flags        = Utilities.ToUInt32LittleEndian(buffer, offset + 0x08);
            hdr.Capacity     = Utilities.ToUInt32LittleEndian(buffer, offset + 0x0C);
            hdr.GrainSize    = Utilities.ToUInt32LittleEndian(buffer, offset + 0x10);
            hdr.GdOffset     = Utilities.ToUInt32LittleEndian(buffer, offset + 0x14);
            hdr.NumGdEntries = Utilities.ToUInt32LittleEndian(buffer, offset + 0x18);
            hdr.FreeSector   = Utilities.ToUInt32LittleEndian(buffer, offset + 0x1C);

            hdr.SavedGeneration = Utilities.ToUInt32LittleEndian(buffer, offset + 0x660);
            hdr.UncleanShutdown = Utilities.ToUInt32LittleEndian(buffer, offset + 0x66C);

            hdr.NumGTEsPerGT = 4096;

            return(hdr);
        }
 public GlobalDirectoryExtent(ServerSparseExtentHeader header)
     : base(header.GdOffset * Sizes.Sector, Utilities.RoundUp(header.NumGdEntries * 4, Sizes.Sector))
 {
     _buffer = new byte[Length];
 }
 public GrainTableExtent(long outputStart, SparseStream content, ServerSparseExtentHeader header)
     : base(outputStart, CalcSize(content, header))
 {
     _content = content;
     _header  = header;
 }