public static void ExtendGPTPartition(GPTPartition partition, long numberOfAdditionalExtentSectors) { Disk disk = partition.Disk; GuidPartitionTableHeader primaryHeader = GuidPartitionTableHeader.ReadPrimaryFromDisk(disk); GuidPartitionTableHeader secondaryHeader = GuidPartitionTableHeader.ReadSecondaryFromDisk(disk, primaryHeader); if (primaryHeader == null || secondaryHeader == null) { throw new NotImplementedException("Cannot extend GPT disk with corrupted header"); } if (primaryHeader.PartitionArrayCRC32 != secondaryHeader.PartitionArrayCRC32) { throw new NotImplementedException("Cannot extend GPT disk with mismatched partition arrays"); } List <GuidPartitionEntry> entries = GuidPartitionTable.ReadEntriesFromDisk(disk); foreach (GuidPartitionEntry entry in entries) { if ((long)entry.FirstLBA == partition.FirstSector) { entry.LastLBA += (ulong)numberOfAdditionalExtentSectors; GuidPartitionEntry.WriteToDisk(disk, primaryHeader, entry); GuidPartitionEntry.WriteToDisk(disk, secondaryHeader, entry); break; } } primaryHeader.PartitionArrayCRC32 = GuidPartitionTable.ComputePartitionArrayCRC32(disk, primaryHeader); GuidPartitionTableHeader.WriteToDisk(disk, primaryHeader); secondaryHeader.PartitionArrayCRC32 = GuidPartitionTable.ComputePartitionArrayCRC32(disk, secondaryHeader); GuidPartitionTableHeader.WriteToDisk(disk, secondaryHeader); }
public static void ExtendPartition(Partition volume, long numberOfAdditionalExtentSectors) { if (volume is MBRPartition) { MBRPartition partition = (MBRPartition)volume; ExtendMBRPartition(partition, numberOfAdditionalExtentSectors); } else if (volume is GPTPartition) { GPTPartition partition = (GPTPartition)volume; ExtendGPTPartition(partition, numberOfAdditionalExtentSectors); } }
/// <returns>Number of bytes</returns> public static long GetMaximumSizeToExtendGPTPartition(GPTPartition partition) { GuidPartitionTableHeader header = GuidPartitionTableHeader.ReadFromDisk(partition.Disk); long partitonEndSector = partition.FirstSector + partition.Size / partition.BytesPerSector; // Prevent from extending beyond the secondary GPT header / partition array long max = ((long)header.LastUsableLBA + 1) * partition.BytesPerSector - (partition.FirstSector * partition.BytesPerSector + partition.Size); List <GuidPartitionEntry> entries = GuidPartitionTable.ReadEntriesFromDisk(partition.Disk); foreach (GuidPartitionEntry entry in entries) { if ((long)entry.FirstLBA > partition.FirstSector) { long available = ((long)entry.FirstLBA - partition.FirstSector) * partition.BytesPerSector - partition.Size; max = Math.Min(max, available); } } return(max); }
public static List <Partition> GetPartitions(Disk disk) { List <Partition> result = new List <Partition>(); MasterBootRecord mbr = MasterBootRecord.ReadFromDisk(disk); if (mbr != null) { if (!mbr.IsGPTBasedDisk) { for (int index = 0; index < mbr.PartitionTable.Length; index++) { PartitionTableEntry entry = mbr.PartitionTable[index]; if (entry.SectorCountLBA > 0) { long size = entry.SectorCountLBA * disk.BytesPerSector; MBRPartition partition = new MBRPartition(entry.PartitionType, disk, entry.FirstSectorLBA, size); result.Add(partition); } } } else { List <GuidPartitionEntry> entries = GuidPartitionTable.ReadEntriesFromDisk(disk); if (entries != null) { foreach (GuidPartitionEntry entry in entries) { GPTPartition partition = new GPTPartition(entry.PartitionGuid, entry.PartitionTypeGuid, entry.PartitionName, disk, (long)entry.FirstLBA, (long)(entry.SizeLBA * (uint)disk.BytesPerSector)); result.Add(partition); } } } } return(result); }