コード例 #1
0
        /// <summary>
        /// Creates a new primary partition with a target size.
        /// </summary>
        /// <param name="size">The target size (in bytes).</param>
        /// <param name="type">The partition type.</param>
        /// <param name="active">Whether the partition is active (bootable).</param>
        /// <returns>The index of the new partition.</returns>
        public override int Create(long size, WellKnownPartitionType type, bool active)
        {
            if (size < _diskGeometry.BytesPerSector)
            {
                throw new ArgumentOutOfRangeException(nameof(size), size, "size must be at least one sector");
            }

            long sectorLength = size / _diskGeometry.BytesPerSector;
            long start        = FindGap(size / _diskGeometry.BytesPerSector, 1);

            return(Create(start, start + sectorLength - 1, GuidPartitionTypes.Convert(type), 0, "Data Partition"));
        }
コード例 #2
0
        /// <summary>
        /// Creates a new partition that encompasses the entire disk.
        /// </summary>
        /// <param name="type">The partition type.</param>
        /// <param name="active">Whether the partition is active (bootable).</param>
        /// <returns>The index of the partition.</returns>
        /// <remarks>The partition table must be empty before this method is called,
        /// otherwise IOException is thrown.</remarks>
        public override int Create(WellKnownPartitionType type, bool active)
        {
            List <GptEntry> allEntries = new List <GptEntry>(GetAllEntries());

            EstablishReservedPartition(allEntries);

            // Fill the rest of the disk with the requested partition
            long start = FirstAvailableSector(allEntries);
            long end   = FindLastFreeSector(start, allEntries);

            return(Create(start, end, GuidPartitionTypes.Convert(type), 0, "Data Partition"));
        }
コード例 #3
0
        /// <summary>
        /// Creates a new partition that encompasses the entire disk.
        /// </summary>
        /// <param name="type">The partition type</param>
        /// <param name="active">Whether the partition is active (bootable)</param>
        /// <returns>The index of the partition</returns>
        /// <remarks>The partition table must be empty before this method is called,
        /// otherwise IOException is thrown.</remarks>
        public override int Create(WellKnownPartitionType type, bool active)
        {
            List <GptEntry> allEntries = new List <GptEntry>(GetAllEntries());

            // If no MicrosoftReserved partition, and no Microsoft Data partitions, and the disk
            // has a 'reasonable' size free, create a Microsoft Reserved partition.
            if (CountEntries(allEntries, e => e.PartitionType == GuidPartitionTypes.MicrosoftReserved) == 0 &&
                CountEntries(allEntries, e => e.PartitionType == GuidPartitionTypes.WindowsBasicData) == 0 &&
                _diskGeometry.Capacity > 512 * 1024 * 1024)
            {
                long reservedStart = FirstAvailableSector(allEntries);
                long reservedEnd   = FindLastFreeSector(reservedStart, allEntries);

                if ((reservedEnd - reservedStart + 1) * _diskGeometry.BytesPerSector > 512 * 1024 * 1024)
                {
                    long size = ((_diskGeometry.Capacity < (16 * 1024L * 1024 * 1024)) ? 32 : 128) * 1024 * 1024;
                    reservedEnd = reservedStart + (size / _diskGeometry.BytesPerSector) - 1;

                    int      reservedOffset   = GetFreeEntryOffset();
                    GptEntry newReservedEntry = new GptEntry();
                    newReservedEntry.PartitionType         = GuidPartitionTypes.MicrosoftReserved;
                    newReservedEntry.Identity              = Guid.NewGuid();
                    newReservedEntry.FirstUsedLogicalBlock = reservedStart;
                    newReservedEntry.LastUsedLogicalBlock  = reservedEnd;
                    newReservedEntry.Attributes            = 0;
                    newReservedEntry.Name = "Microsoft reserved partition";
                    newReservedEntry.WriteTo(_entryBuffer, reservedOffset);
                    allEntries.Add(newReservedEntry);
                }
            }

            // Fill the rest of the disk with the requested partition
            long start = FirstAvailableSector(allEntries);
            long end   = FindLastFreeSector(start, allEntries);

            int      offset   = GetFreeEntryOffset();
            GptEntry newEntry = new GptEntry();

            newEntry.PartitionType         = GuidPartitionTypes.Convert(type);
            newEntry.Identity              = Guid.NewGuid();
            newEntry.FirstUsedLogicalBlock = start;
            newEntry.LastUsedLogicalBlock  = end;
            newEntry.Attributes            = 0;
            newEntry.Name = "Data Partition";
            newEntry.WriteTo(_entryBuffer, offset);

            // Commit changes to disk
            Write();

            return(GetEntryIndex(newEntry.Identity));
        }
コード例 #4
0
        /// <summary>
        /// Creates a new aligned partition with a target size.
        /// </summary>
        /// <param name="size">The target size (in bytes).</param>
        /// <param name="type">The partition type.</param>
        /// <param name="active">Whether the partition is active (bootable).</param>
        /// <param name="alignment">The alignment (in bytes).</param>
        /// <returns>The index of the new partition.</returns>
        /// <remarks>
        /// Traditionally partitions were aligned to the physical structure of the underlying disk,
        /// however with modern storage greater efficiency is achieved by aligning partitions on
        /// large values that are a power of two.
        /// </remarks>
        public override int CreateAligned(long size, WellKnownPartitionType type, bool active, int alignment)
        {
            if (size < _diskGeometry.BytesPerSector)
            {
                throw new ArgumentOutOfRangeException(nameof(size), size, "size must be at least one sector");
            }

            if (alignment % _diskGeometry.BytesPerSector != 0)
            {
                throw new ArgumentException("Alignment is not a multiple of the sector size");
            }

            if (size % alignment != 0)
            {
                throw new ArgumentException("Size is not a multiple of the alignment");
            }

            long sectorLength = size / _diskGeometry.BytesPerSector;
            long start        = FindGap(size / _diskGeometry.BytesPerSector, alignment / _diskGeometry.BytesPerSector);

            return(Create(start, start + sectorLength - 1, GuidPartitionTypes.Convert(type), 0, "Data Partition"));
        }
コード例 #5
0
        /// <summary>
        /// Creates a new aligned partition that encompasses the entire disk.
        /// </summary>
        /// <param name="type">The partition type</param>
        /// <param name="active">Whether the partition is active (bootable)</param>
        /// <param name="alignment">The alignment (in bytes)</param>
        /// <returns>The index of the partition</returns>
        /// <remarks>The partition table must be empty before this method is called,
        /// otherwise IOException is thrown.</remarks>
        /// <remarks>
        /// Traditionally partitions were aligned to the physical structure of the underlying disk,
        /// however with modern storage greater efficiency is acheived by aligning partitions on
        /// large values that are a power of two.
        /// </remarks>
        public override int CreateAligned(WellKnownPartitionType type, bool active, int alignment)
        {
            if (alignment % _diskGeometry.BytesPerSector != 0)
            {
                throw new ArgumentException("Alignment is not a multiple of the sector size");
            }

            List <GptEntry> allEntries = new List <GptEntry>(GetAllEntries());

            EstablishReservedPartition(allEntries);

            // Fill the rest of the disk with the requested partition
            long start = Utilities.RoundUp(FirstAvailableSector(allEntries), alignment / _diskGeometry.BytesPerSector);
            long end   = Utilities.RoundDown(FindLastFreeSector(start, allEntries) + 1, alignment / _diskGeometry.BytesPerSector);

            if (end <= start)
            {
                throw new IOException("No available space");
            }

            return(Create(start, end - 1, GuidPartitionTypes.Convert(type), 0, "Data Partition"));
        }