public ExtendedPartitionHelper ExtendedPartition(int hdNumberToGet, long newHdSize)
{
var lbsByte = _imageSchema.HardDrives[hdNumberToGet].Lbs;
var extendedPartitionHelper = new ExtendedPartitionHelper();
//Determine if any Extended or Logical Partitions are present. Needed ahead of time correctly calculate sizes.
//And calculate minimum needed extended partition size
bool schemaHasExtendedPartition = false;
string logicalFsType = null;
foreach (var part in _imageSchema.HardDrives[hdNumberToGet].Partitions.Where(part => part.Active))
{
if (part.Type.ToLower() == "extended")
{
schemaHasExtendedPartition = true;
}
if (part.Type.ToLower() != "logical") continue;
extendedPartitionHelper.LogicalCount++;
logicalFsType = part.FsType;
extendedPartitionHelper.HasLogical = true;
}
if (!schemaHasExtendedPartition) return extendedPartitionHelper;
if (logicalFsType != null &&
(extendedPartitionHelper.LogicalCount == 1 && logicalFsType.ToLower() == "swap"))
extendedPartitionHelper.IsOnlySwap = true;
var partitionCounter = -1;
foreach (var partition in _imageSchema.HardDrives[hdNumberToGet].Partitions)
{
partitionCounter++;
if (!partition.Active && partition.Type.ToLower() != "extended" && partition.Type.ToLower() != "logical")
continue;
if (partition.Type.ToLower() == "extended")
{
if (partition.ForceFixedSize)
{
extendedPartitionHelper.MinSizeBlk = partition.Size;
return extendedPartitionHelper;
}
if (!string.IsNullOrEmpty(partition.CustomSize) && !string.IsNullOrEmpty(partition.CustomSizeUnit))
{
long customSizeBytes = 0;
switch (partition.CustomSizeUnit)
{
case "MB":
customSizeBytes = Convert.ToInt64(partition.CustomSize) * 1024 * 1024;
break;
case "GB":
customSizeBytes = Convert.ToInt64(partition.CustomSize) * 1024 * 1024 * 1024;
break;
case "%":
double hdPercent = Convert.ToDouble(partition.CustomSize) / 100;
customSizeBytes = Convert.ToInt64(hdPercent * newHdSize);
break;
}
extendedPartitionHelper.MinSizeBlk = customSizeBytes / lbsByte;
return extendedPartitionHelper;
}
//If Hd has extended but no logical, use the extended to calc size
if (!extendedPartitionHelper.HasLogical)
{
//In this case someone has defined an extended partition but has not created any logical
//This could just be for preperation of leaving room for more logical partition later
//This should be highly unlikely but should account for it anyway. There is no way of knowing a minimum size required
//while still having the partition be resizable. So will set minimum sized required to unless user overrides
//set arbitary minimum to 100MB
extendedPartitionHelper.MinSizeBlk = 100 * 1024 * 1024 / lbsByte;
return extendedPartitionHelper;
}
}
else if (partition.Type.ToLower() == "logical")
{
//Check if the logical partition is a physical volume for a volume group
if (partition.FsId.ToLower() == "8e" || partition.FsId.ToLower() == "8e00")
{
//Add to the minimum extended size the minimum size of the volume group
var volumeGroupHelper = VolumeGroup(hdNumberToGet, partitionCounter, newHdSize);
extendedPartitionHelper.MinSizeBlk += volumeGroupHelper.MinSizeBlk;
if (volumeGroupHelper.MinSizeBlk == 0)
extendedPartitionHelper.MinSizeBlk += partition.Size;
}
else
{
var partitionHelper = Partition(hdNumberToGet, partitionCounter, newHdSize);
extendedPartitionHelper.MinSizeBlk += partitionHelper.MinSizeBlk;
}
}
}
//Logical paritions default to 1MB more than the previous block using fdisk. This needs to be added to extended size so logical parts will fit inside
long epPadding = (((1048576/lbsByte)*extendedPartitionHelper.LogicalCount) + (1048576/lbsByte));
extendedPartitionHelper.MinSizeBlk += epPadding;
return extendedPartitionHelper;
}