private static async Task EnsureFormatted(Partition partition, string label, FileSystemFormat fileSystemFormat) { var volume = await partition.GetVolume(); if (volume == null) { throw new ApplicationException($"Couldn't get volume for {partition}"); } await volume.Mount(); if (Directory.EnumerateFileSystemEntries(volume.Root).Count() > 1) { throw new ApplicationException("The format operation failed. The drive shouldn't contain any file after the format"); } var sameLabel = string.Equals(volume.Label, label); var sameFileSystemFormat = Equals(volume.FileSytemFormat, fileSystemFormat); if (!sameLabel || !sameFileSystemFormat) { Log.Verbose("Same label? {Value}. Same file system format? {Value}", sameLabel, sameFileSystemFormat); throw new ApplicationException("The format operation failed"); } }
private async Task <Volume> GetVolumeCore(Partition partition) { Log.Debug("Getting volume of {Partition}", partition); var results = await ps.ExecuteCommand("Get-Volume", ("Partition", await GetPsPartition(partition))); var result = results.FirstOrDefault()?.ImmediateBaseObject; if (result == null) { throw new ApplicationException($"Cannot get volume for {partition}"); } var vol = new Volume(partition) { Partition = partition, Size = new ByteSize(Convert.ToUInt64(result.GetPropertyValue("Size"))), Label = (string)result.GetPropertyValue("FileSystemLabel"), Letter = (char?)result.GetPropertyValue("DriveLetter"), FileSytemFormat = FileSystemFormat.FromString((string)result.GetPropertyValue("FileSystem")), }; Log.Debug("Obtained {Volume}", vol); return(vol); }
public async Task AssignDriveLetter(Partition partition, char driveLetter) { await Observable .Defer(() => Observable .FromAsync(() => ChangeDriveLetterCore(partition, driveLetter))) .RetryWithBackoffStrategy(5); Log.Debug("{Partition} mounted successfully as driver letter {Letter}", partition, driveLetter); }
public async Task RemovePartition(Partition partition) { Log.Verbose("Removing {Partition}", partition); using (var c = await GptContextFactory.Create(partition.Disk.Number, FileAccess.ReadWrite)) { var gptPart = c.Find(partition.Guid); c.Delete(gptPart); } await partition.Disk.Refresh(); }
private async Task ChangeDriveLetterCore(Partition partition, char driveLetter) { Log.Debug("Assigning drive letter {Letter} to {Partition}", driveLetter, partition); var psPart = await GetPsPartition(partition); await ps.ExecuteCommand("Set-Partition", ("InputObject", psPart), ("NewDriveLetter", driveLetter)); Log.Debug("Ensuring the volume is mounted..."); EnsurePathExists($"{driveLetter}:\\"); }
private async Task <PSObject> GetPsPartition(Partition partition) { var psDataCollection = await ps.ExecuteScript($"Get-Partition -DiskNumber {partition.Disk.Number} | where -Property Guid -eq '{{{partition.Guid}}}'"); var psPartition = psDataCollection.FirstOrDefault(); if (psPartition == null) { await partition.Disk.Refresh(); throw new ApplicationException($"Could not get PS Partition for {partition}"); } return(psPartition); }
public async Task Clean(IPhone toClean) { Log.Information("Performing partition cleanup"); disk = await toClean.GetDeviceDisk(); dataPartition = await disk.GetPartitionByName(PartitionName.Data); await RemoveAnyPartitionsAfterData(); await EnsureDataIsLastPartition(); Log.Information("Cleanup done"); await disk.Refresh(); }
private async Task FormatCore(Partition partition, FileSystemFormat fileSystemFormat, string label = null) { label = label ?? partition.Name ?? ""; Log.Verbose(@"Formatting {Partition} as {Format} labeled as ""{Label}""", partition, fileSystemFormat, label); var part = await GetPsPartition(partition); await ps.ExecuteCommand("Format-Volume", ("Partition", part), ("Force", null), ("Confirm", false), ("FileSystem", fileSystemFormat.Moniker), ("NewFileSystemLabel", label) ); await EnsureFormatted(partition, label, fileSystemFormat); }
public async Task SetGptType(Partition partition, PartitionType partitionType) { Log.Verbose("Setting new GPT partition type {Type} to {Partition}", partitionType, partition); if (Equals(partition.PartitionType, partitionType)) { return; } using (var context = await GptContextFactory.Create(partition.Disk.Number, FileAccess.ReadWrite, GptContext.DefaultBytesPerSector, GptContext.DefaultChunkSize)) { var part = context.Find(partition.Guid); part.PartitionType = partitionType; } await partition.Disk.Refresh(); Log.Verbose("New GPT type set correctly", partitionType, partition); }
public async Task Clean(IPhone toClean) { Log.Information("Performing partition cleanup"); disk = await toClean.GetDeviceDisk(); dataPartition = await disk.GetPartition(PartitionName.Data); if (dataPartition == null) { Log.Verbose("Data partition not found. Skipping cleanup."); return; } await RemoveAnyPartitionsAfterData(); await EnsureDataIsLastPartition(); Log.Information("Cleanup done"); await disk.Refresh(); }
public async Task ResizePartition(Partition partition, ByteSize size) { if (size.MegaBytes < 0) { throw new InvalidOperationException($"The partition size cannot be negative: {size}"); } var sizeBytes = (ulong)size.Bytes; Log.Verbose("Resizing partition {Partition} to {Size}", partition, size); var psPart = await GetPsPartition(partition); await ps.ExecuteCommand("Resize-Partition", ("InputObject", psPart), ("Size", sizeBytes)); if (ps.HadErrors) { Throw("The resize operation has failed"); } }
public async Task Format(Partition partition, FileSystemFormat fileSystemFormat, string label = null) { await Observable.FromAsync(() => FormatCore(partition, fileSystemFormat, label)).RetryWithBackoffStrategy(4); }
public async Task <Volume> GetVolume(Partition partition) { return(await Observable.FromAsync(() => GetVolumeCore(partition)).RetryWithBackoffStrategy(4)); }