public static List <DiskExtent> GetUnallocatedExtents(Disk disk) { MasterBootRecord mbr = MasterBootRecord.ReadFromDisk(disk); List <DiskExtent> result = new List <DiskExtent>(); if (mbr == null) { result.Add(new DiskExtent(disk, 0, disk.Size)); return(result); } else { long dataRegionStartSector; long dataRegionSize; if (!mbr.IsGPTBasedDisk) { dataRegionStartSector = MBRDiskFirstUsableSector; dataRegionSize = Math.Min(disk.Size, UInt32.MaxValue * disk.BytesPerSector) - dataRegionStartSector; } else { GuidPartitionTableHeader gptHeader = GuidPartitionTableHeader.ReadFromDisk(disk); dataRegionStartSector = (long)gptHeader.FirstUsableLBA; dataRegionSize = (long)(gptHeader.LastUsableLBA - gptHeader.FirstUsableLBA + 1) * disk.BytesPerSector; } List <Partition> partitions = GetPartitions(disk); List <DiskExtent> usedExtents = new List <DiskExtent>(); foreach (Partition partition in partitions) { usedExtents.Add(partition.Extent); } return(DiskExtentsHelper.GetUnallocatedExtents(disk, dataRegionStartSector, dataRegionSize, usedExtents)); } }
/// <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); }