From fc7e07df2e154fce734c3f3d022903ba88b7974d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20N=C3=B8rfjand=20Stengaard?= Date: Thu, 1 Dec 2022 21:22:21 +0100 Subject: [PATCH] Add rdb update command --- src/Hst.Imager.ConsoleApp/CommandHandler.cs | 7 ++ .../Presenters/RdbInfoPresenter.cs | 6 +- .../RdbCommandFactory.cs | 40 +++++++ src/Hst.Imager.ConsoleApp/readme.md | 47 +++++++- .../Commands/RdbUpdateCommand.cs | 111 ++++++++++++++++++ 5 files changed, 205 insertions(+), 6 deletions(-) create mode 100644 src/Hst.Imager.Core/Commands/RdbUpdateCommand.cs diff --git a/src/Hst.Imager.ConsoleApp/CommandHandler.cs b/src/Hst.Imager.ConsoleApp/CommandHandler.cs index 195da28..008ae24 100644 --- a/src/Hst.Imager.ConsoleApp/CommandHandler.cs +++ b/src/Hst.Imager.ConsoleApp/CommandHandler.cs @@ -253,6 +253,13 @@ await Execute(new RdbInitCommand(GetLogger(), GetCommandHelper() await GetPhysicalDrives(), path, name, ParseSize(size), chs, rdbBlockLo)); } + public static async Task RdbUpdate(string path, uint? flags, uint? hostId, string diskProduct, + string diskRevision, string diskVendor) + { + await Execute(new RdbUpdateCommand(GetLogger(), GetCommandHelper(), + await GetPhysicalDrives(), path, flags, hostId, diskProduct, diskRevision, diskVendor)); + } + public static async Task RdbFsAdd(string path, string fileSystemPath, string dosType, string fileSystemName) { await Execute(new RdbFsAddCommand(GetLogger(), GetCommandHelper(), diff --git a/src/Hst.Imager.ConsoleApp/Presenters/RdbInfoPresenter.cs b/src/Hst.Imager.ConsoleApp/Presenters/RdbInfoPresenter.cs index 7fa51f5..34194b2 100644 --- a/src/Hst.Imager.ConsoleApp/Presenters/RdbInfoPresenter.cs +++ b/src/Hst.Imager.ConsoleApp/Presenters/RdbInfoPresenter.cs @@ -25,7 +25,7 @@ public static string Present(RdbInfo rdbInfo) { Columns = new[] { - new Column { Name = "Name" }, + new Column { Name = "Product" }, new Column { Name = "Vendor" }, new Column { Name = "Revision" }, new Column { Name = "Size", Alignment = ColumnAlignment.Right }, @@ -33,6 +33,8 @@ public static string Present(RdbInfo rdbInfo) new Column { Name = "Heads", Alignment = ColumnAlignment.Right }, new Column { Name = "Sectors", Alignment = ColumnAlignment.Right }, new Column { Name = "Block Size", Alignment = ColumnAlignment.Right }, + new Column { Name = "Flags", Alignment = ColumnAlignment.Right }, + new Column { Name = "Host Id", Alignment = ColumnAlignment.Right }, new Column { Name = "Rdb Block Lo", Alignment = ColumnAlignment.Right }, new Column { Name = "Rdb Block Hi", Alignment = ColumnAlignment.Right } }, @@ -48,6 +50,8 @@ public static string Present(RdbInfo rdbInfo) rigidDiskBlock.Heads.ToString(), rigidDiskBlock.Sectors.ToString(), rigidDiskBlock.BlockSize.ToString(), + rigidDiskBlock.Flags.ToString(), + rigidDiskBlock.HostId.ToString(), rigidDiskBlock.RdbBlockLo.ToString(), rigidDiskBlock.RdbBlockHi.ToString() } diff --git a/src/Hst.Imager.ConsoleApp/RdbCommandFactory.cs b/src/Hst.Imager.ConsoleApp/RdbCommandFactory.cs index e2f1b21..1a4a037 100644 --- a/src/Hst.Imager.ConsoleApp/RdbCommandFactory.cs +++ b/src/Hst.Imager.ConsoleApp/RdbCommandFactory.cs @@ -12,6 +12,7 @@ public static Command CreateRdbCommand() rdbCommand.AddCommand(CreateRdbInit()); rdbCommand.AddCommand(CreateRdbFs()); rdbCommand.AddCommand(CreateRdbPart()); + rdbCommand.AddCommand(CreateRdbUpdate()); return rdbCommand; } @@ -573,5 +574,44 @@ private static Command CreateRdbPartFormat() return rdbPartFormatCommand; } + + private static Command CreateRdbUpdate() + { + var pathArgument = new Argument( + name: "Path", + description: "Path to physical drive or image file."); + + var flagsOption = new Option( + new[] { "--flags", "-f" }, + description: "Flags."); + + var hostIdOption = new Option( + new[] { "--host-id", "-h" }, + description: "Host id."); + + var diskProductOption = new Option( + new[] { "--disk-product", "-dp" }, + description: "Disk product."); + + var diskRevisionOption = new Option( + new[] { "--disk-revision", "-dr" }, + description: "Disk revision."); + + var diskVendorOption = new Option( + new[] { "--disk-vendor", "-dv" }, + description: "Disk vendor."); + + var command = new Command("update", "Update Rigid Disk Block."); + command.SetHandler(CommandHandler.RdbUpdate, pathArgument, flagsOption, hostIdOption, + diskProductOption, diskRevisionOption, diskVendorOption); + command.AddArgument(pathArgument); + command.AddOption(flagsOption); + command.AddOption(hostIdOption); + command.AddOption(diskProductOption); + command.AddOption(diskRevisionOption); + command.AddOption(diskVendorOption); + + return command; + } } } \ No newline at end of file diff --git a/src/Hst.Imager.ConsoleApp/readme.md b/src/Hst.Imager.ConsoleApp/readme.md index fe3a8cd..5fead4d 100644 --- a/src/Hst.Imager.ConsoleApp/readme.md +++ b/src/Hst.Imager.ConsoleApp/readme.md @@ -287,6 +287,25 @@ Example of initializing Rigid Disk Block using cylinders, heads and sectors on a hst.imager rdb init 4gb.vhd -chs 800,16,63 ``` +## Update Rigid Disk Block + +Updates Rigid Disk Block properties: +- Flags +- Host id +- Disk product +- Disk revision +- Disk vendor + +Example of displaying usage for updating Rigid Disk Block: +``` +hst.imager rdb update +``` + +Example of updating flags property to 7 in Rigid Disk Block on a 4GB vhd image file: +``` +hst.imager rdb update 4gb.vhd --flags 7 +``` + ## Add file system to Rigid Disk Block Adds a file system to Rigid Disk Block. @@ -355,7 +374,10 @@ hst.imager rdb fs import 4gb.vhd amiga-os-310-install.adf DOS3 FastFileSystem ## Update file system in Rigid Disk Block -Updates a file system in Rigid Disk Block. +Updates file system properties in Rigid Disk Block: +- DOS type +- File system name +- File system data DOS Type updates will also update partitions using Dos type defined for file system. @@ -364,11 +386,16 @@ Example of displaying usage for updating a file system in Rigid Disk Block: hst.imager rdb fs update ``` -Example of updating file system number 1 with dos type PFS3 in Rigid Disk Block on a 4GB vhd image file: +Example of updating file system number 1 with dos type property to PFS3 in Rigid Disk Block on a 4GB vhd image file: ``` hst.imager rdb fs update 4gb.vhd 1 --dos-type PFS3 ``` +Example of updating file system number 1 with data from file in Rigid Disk Block on a 4GB vhd image file: +``` +hst.imager rdb fs update 4gb.vhd 1 --path pfs3aio +``` + ## Add partition to Rigid Disk Block Adds a partition to Rigid Disk Block with a defined size. @@ -473,19 +500,29 @@ hst.imager rdb part kill 4gb.vhd 1 50465301 ## Update partition in Rigid Disk Block -Updates a partition in Rigid Disk Block. +Updates partition properties in Rigid Disk Block: +- Name +- DOS Type +- Reserved +- Pre alloc +- Buffers +- Max transfer +- Mask +- No mount +- Bootable +- Priority Example of displaying usage for updating a partition in Rigid Disk Block: ``` hst.imager rdb part update ``` -Example of updating partition number 1 setting it bootable in Rigid Disk Block on a 4GB vhd image file: +Example of updating partition number 1 setting bootable property to true in Rigid Disk Block on a 4GB vhd image file: ``` hst.imager rdb part update 4gb.vhd 1 --bootable true ``` -Example of updating partition number 1 setting max transfer to 130560 in Rigid Disk Block on a 4GB vhd image file: +Example of updating partition number 1 setting max transfer property to 130560 in Rigid Disk Block on a 4GB vhd image file: ``` hst.imager rdb part update 4gb.vhd 1 --max-transfer 130560 ``` \ No newline at end of file diff --git a/src/Hst.Imager.Core/Commands/RdbUpdateCommand.cs b/src/Hst.Imager.Core/Commands/RdbUpdateCommand.cs new file mode 100644 index 0000000..8707373 --- /dev/null +++ b/src/Hst.Imager.Core/Commands/RdbUpdateCommand.cs @@ -0,0 +1,111 @@ +namespace Hst.Imager.Core.Commands; + +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using Amiga.RigidDiskBlocks; +using Hst.Core; +using Microsoft.Extensions.Logging; + +public class RdbUpdateCommand : CommandBase +{ + private readonly ILogger logger; + private readonly ICommandHelper commandHelper; + private readonly IEnumerable physicalDrives; + private readonly string path; + private readonly uint? flags; + private readonly uint? hostId; + private readonly string diskProduct; + private readonly string diskRevision; + private readonly string diskVendor; + + public RdbUpdateCommand(ILogger logger, ICommandHelper commandHelper, + IEnumerable physicalDrives, string path, uint? flags, uint? hostId, string diskProduct, + string diskRevision, string diskVendor) + { + this.logger = logger; + this.commandHelper = commandHelper; + this.physicalDrives = physicalDrives; + this.path = path; + this.flags = flags; + this.hostId = hostId; + this.diskProduct = diskProduct; + this.diskRevision = diskRevision; + this.diskVendor = diskVendor; + } + + public override async Task Execute(CancellationToken token) + { + OnInformationMessage($"Updating Rigid Disk Block at '{path}'"); + + OnDebugMessage($"Opening '{path}' as writable"); + + var mediaResult = commandHelper.GetWritableMedia(physicalDrives, path, allowPhysicalDrive: true); + if (mediaResult.IsFaulted) + { + return new Result(mediaResult.Error); + } + + using var media = mediaResult.Value; + await using var stream = media.Stream; + + OnDebugMessage("Reading Rigid Disk Block"); + + var rigidDiskBlock = await commandHelper.GetRigidDiskBlock(stream); + + if (rigidDiskBlock == null) + { + return new Result(new Error("Rigid Disk Block not found")); + } + + if (flags.HasValue) + { + OnDebugMessage($"Updating flags '{flags.Value}'"); + + rigidDiskBlock.Flags = flags.Value; + + OnInformationMessage($"Flags '{flags.Value}'"); + } + + if (hostId.HasValue) + { + OnDebugMessage($"Updating host id '{hostId.Value}'"); + + rigidDiskBlock.HostId = hostId.Value; + + OnInformationMessage($"Host id '{hostId.Value}'"); + } + + if (!string.IsNullOrWhiteSpace(diskProduct)) + { + OnDebugMessage($"Updating disk product '{diskProduct}'"); + + rigidDiskBlock.DiskProduct = diskProduct; + + OnInformationMessage($"Disk product '{diskProduct}'"); + } + + if (!string.IsNullOrWhiteSpace(diskRevision)) + { + OnDebugMessage($"Updating disk revision '{diskRevision}'"); + + rigidDiskBlock.DiskRevision = diskRevision; + + OnInformationMessage($"Disk revision '{diskRevision}'"); + } + + if (!string.IsNullOrWhiteSpace(diskVendor)) + { + OnDebugMessage($"Updating disk vendor '{diskVendor}'"); + + rigidDiskBlock.DiskVendor = diskVendor; + + OnInformationMessage($"Disk vendor '{diskVendor}'"); + } + + OnDebugMessage("Writing Rigid Disk Block"); + await RigidDiskBlockWriter.WriteBlock(rigidDiskBlock, stream); + + return new Result(); + } +} \ No newline at end of file