예제 #1
0
        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");
            }
        }
예제 #2
0
        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);
        }
예제 #3
0
        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);
        }
예제 #4
0
        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();
        }
예제 #5
0
        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}:\\");
        }
예제 #6
0
        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);
        }
예제 #7
0
        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();
        }
예제 #8
0
        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);
        }
예제 #9
0
        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);
        }
예제 #10
0
        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();
        }
예제 #11
0
        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");
            }
        }
예제 #12
0
 public async Task Format(Partition partition, FileSystemFormat fileSystemFormat, string label = null)
 {
     await Observable.FromAsync(() => FormatCore(partition, fileSystemFormat, label)).RetryWithBackoffStrategy(4);
 }
예제 #13
0
 public async Task <Volume> GetVolume(Partition partition)
 {
     return(await Observable.FromAsync(() => GetVolumeCore(partition)).RetryWithBackoffStrategy(4));
 }