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)); } }
public static Guid?GetWindowsVolumeGuid(Volume volume) { if (volume is MBRPartition) { MBRPartition partition = (MBRPartition)volume; MasterBootRecord mbr = MasterBootRecord.ReadFromDisk(((MBRPartition)volume).Disk); return(GetWindowsVolumeGuid(mbr.DiskSignature, (ulong)(partition.FirstSector * partition.BytesPerSector))); } else if (volume is GPTPartition) { return(((GPTPartition)volume).VolumeGuid); } else if (volume is DynamicVolume) { return(((DynamicVolume)volume).VolumeGuid); } else if (volume is OperatingSystemVolume) { return(((OperatingSystemVolume)volume).VolumeGuid); } else { return(null); } }
public static void ExtendMBRPartition(MBRPartition partition, long numberOfAdditionalExtentSectors) { Disk disk = partition.Disk; MasterBootRecord mbr = MasterBootRecord.ReadFromDisk(disk); for (int index = 0; index < mbr.PartitionTable.Length; index++) { if (mbr.PartitionTable[index].FirstSectorLBA == partition.FirstSector) { mbr.PartitionTable[index].SectorCountLBA += (uint)numberOfAdditionalExtentSectors; ulong lastSectorLBA = mbr.PartitionTable[index].LastSectorLBA; mbr.PartitionTable[index].LastSectorCHS = CHSAddress.FromLBA(lastSectorLBA, disk); break; } } MasterBootRecord.WriteToDisk(disk, mbr); }
/// <returns>Number of bytes</returns> public static long GetMaximumSizeToExtendMBRPartition(MBRPartition partition) { MasterBootRecord mbr = MasterBootRecord.ReadFromDisk(partition.Disk); long partitonEndSector = partition.FirstSector + partition.Size / partition.BytesPerSector; long max = partition.Disk.Size - (partition.FirstSector * partition.BytesPerSector + partition.Size); foreach (PartitionTableEntry entry in mbr.PartitionTable) { if (entry.FirstSectorLBA > partition.FirstSector) { long available = (entry.FirstSectorLBA - partition.FirstSector) * partition.BytesPerSector - partition.Size; max = Math.Min(max, available); } } // MBR partition cannot be larger than 2^32 sectors max = Math.Min(max, UInt32.MaxValue * partition.BytesPerSector); return(max); }
public static Guid?GetVolumeUniqueID(Volume volume) { if (volume is MBRPartition) { MBRPartition partition = (MBRPartition)volume; MasterBootRecord mbr = MasterBootRecord.ReadFromDisk(partition.Disk); byte[] firstSectorBytes = BigEndianConverter.GetBytes(partition.FirstSector); return(new Guid((int)mbr.DiskSignature, 0, 0, firstSectorBytes)); } else if (volume is GPTPartition) { return(((GPTPartition)volume).VolumeGuid); } else if (volume is DynamicVolume) { return(((DynamicVolume)volume).VolumeGuid); } else { return(null); } }
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); }