Esempio n. 1
0
        public static MasterRecord CreateNewVolume([NotNull] IDirectDiskAccess access, ulong size)
        {
            Validate.ArgumentNotNull(access, "access");

            if (size % Constants.BlockSizeBytes != 0)
            {
                throw new ArgumentOutOfRangeException("Volume size should be on block size boundary.");
            }

            if (size <= BlockGroup.ReservedBlocks * Constants.BlockSizeBytes)
            {
                throw new ArgumentOutOfRangeException(string.Format("Min volume size is {0}", Constants.BlockSizeBytes * (BlockGroup.ReservedBlocks + 1)));
            }

            var totalBlocks = (uint)(size / Constants.BlockSizeBytes);
            uint numberOfFullGroups = totalBlocks / Constants.BlocksPerGroup;
            uint remainingBlocks = totalBlocks % Constants.BlocksPerGroup;
            if (remainingBlocks > BlockGroup.ReservedBlocks)
            {
                numberOfFullGroups++;
            }

            var rec = new MasterRecord(access);
            rec._groupsReserved = new BlockGroup[numberOfFullGroups];
            var offset = new Address(32 + (BlockGroupDescriptor.RawSizeBytes * numberOfFullGroups));
            offset = offset.AlignOnBlockBoundary;

            uint totalFreeBlocks = 0;
            for (uint i = 0; i < numberOfFullGroups; ++i)
            {
                bool last = (i == numberOfFullGroups - 1 && remainingBlocks > 0);
                var groupSize = last ? remainingBlocks : Constants.BlocksPerGroup;
                var newGroup = new BlockGroup(offset, groupSize);
                offset = offset.AddBlocks(groupSize);
                totalFreeBlocks += newGroup.Descriptor.NumFreeBlocksInGroup;
                rec._groupsReserved[i] = newGroup;
            }

            rec._freeSpaceBlocks = totalFreeBlocks;
            rec.VolumeSize = offset.Value;
            rec.RootNode = rec.CreateDirectoryNode("\\", null);
            return rec;
        }