From 86d5268bcfc97b6018f5e2ef262273ad568bca3b Mon Sep 17 00:00:00 2001 From: BlubbFish Date: Fri, 22 May 2020 13:25:22 +0200 Subject: [PATCH] Init --- .gitignore | 3 + hp-raid45-recovery.sln | 31 ++++ hp-raid45-recovery/CopyProcess.cs | 131 +++++++++++++++ hp-raid45-recovery/Program.cs | 155 ++++++++++++++++++ .../Properties/launchSettings.json | 8 + hp-raid45-recovery/hp-raid45-recovery.csproj | 14 ++ 6 files changed, 342 insertions(+) create mode 100644 .gitignore create mode 100644 hp-raid45-recovery.sln create mode 100644 hp-raid45-recovery/CopyProcess.cs create mode 100644 hp-raid45-recovery/Program.cs create mode 100644 hp-raid45-recovery/Properties/launchSettings.json create mode 100644 hp-raid45-recovery/hp-raid45-recovery.csproj diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7e4ebba --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/.vs +/hp-raid45-recovery/obj +/hp-raid45-recovery/bin diff --git a/hp-raid45-recovery.sln b/hp-raid45-recovery.sln new file mode 100644 index 0000000..3527cdd --- /dev/null +++ b/hp-raid45-recovery.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.29613.14 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "hp-raid45-recovery", "hp-raid45-recovery\hp-raid45-recovery.csproj", "{ABD4015C-DCD8-49D5-BAFC-CFA70E430EC7}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Utils_Core", "..\Utils\Utils\Utils\Utils_Core.csproj", "{B1015E17-AD3F-4981-BCE3-5EE78FA714F8}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {ABD4015C-DCD8-49D5-BAFC-CFA70E430EC7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {ABD4015C-DCD8-49D5-BAFC-CFA70E430EC7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {ABD4015C-DCD8-49D5-BAFC-CFA70E430EC7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {ABD4015C-DCD8-49D5-BAFC-CFA70E430EC7}.Release|Any CPU.Build.0 = Release|Any CPU + {B1015E17-AD3F-4981-BCE3-5EE78FA714F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B1015E17-AD3F-4981-BCE3-5EE78FA714F8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B1015E17-AD3F-4981-BCE3-5EE78FA714F8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B1015E17-AD3F-4981-BCE3-5EE78FA714F8}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {7CFF96AF-B668-486D-8D0E-F6A37363F73D} + EndGlobalSection +EndGlobal diff --git a/hp-raid45-recovery/CopyProcess.cs b/hp-raid45-recovery/CopyProcess.cs new file mode 100644 index 0000000..205e264 --- /dev/null +++ b/hp-raid45-recovery/CopyProcess.cs @@ -0,0 +1,131 @@ +using System; +using System.IO; + +namespace BlubbFish.Tools.Raid.HP.Raid45 +{ + internal class CopyProcess + { + public Int32[,] Mode { get; } + + public UInt32 Sector { get; private set; } + public UInt32 Stripe { get; private set; } + public UInt32 Parity { get; private set; } + public Int64 Start { get; private set; } + public Int64 End { get; private set; } + public FileStream[] InputDisks { get; private set; } + public FileStream OutputDisk { get; private set; } + + + public CopyProcess() { + this.Mode = new Int32[4, 3] { + { 0, 1, 2 }, + { 0, 1, 3 }, + { 0, 2, 3 }, + { 1, 2, 3 } + }; + } + + internal void SetInputFiles(String disk1, String disk2, String disk3, String disk4) { + this.InputDisks = new FileStream[] { + File.OpenRead(disk1), + File.OpenRead(disk2), + File.OpenRead(disk3), + File.OpenRead(disk4) + }; + } + + internal void SetOutputFile(String output) { + this.OutputDisk = File.OpenWrite(output); + } + + private void Close() { + this.OutputDisk.Close(); + this.InputDisks[0].Close(); + this.InputDisks[1].Close(); + this.InputDisks[2].Close(); + this.InputDisks[3].Close(); + } + + internal void SetParameters(UInt32 sector, UInt32 stripe, UInt32 parity) { + this.Sector = sector; + this.Stripe = stripe; + this.Parity = parity; + } + + internal void SetStartEnd(Int64 start, Int64 end) { + this.Start = start; + this.End = end; + } + + internal void Running() { + Int64 incount = this.Start / this.Stripe; + Int64 outcount = 0; + Console.WriteLine("alloc buffer " + this.Sector); + Span buffer = new Span(new Byte[this.Sector]); + + UInt32 startmode = (UInt32)(this.Start / (this.Stripe * this.Parity)) % 4; + while (true) { + for (UInt32 diskmode = startmode; diskmode < 4; diskmode++) { + Console.WriteLine("Disk Mode: " + diskmode + ", [" + this.Mode[diskmode, 0] + ", " + this.Mode[diskmode, 1] + ", " + this.Mode[diskmode, 2] + "]"); + for (UInt32 paritys = 0; paritys < this.Parity; paritys++) { + try { + for (UInt32 disk = 0; disk < 3; disk++) { + this.Copy(this.Mode[diskmode, disk], incount, outcount, buffer); + outcount++; + } + } catch (Exception e) { + Console.WriteLine("We have an Error while copy, maybe we are at EOF.\n\n" + e.Message); + this.Close(); + return; + } + incount++; + if (incount * this.Stripe >= this.End && this.End != 0) { + Console.WriteLine("done"); + this.Close(); + return; + } + } + } + startmode = 0; + } + } + + private void Copy(Int32 inputdisk, Int64 incount, Int64 outcount, Span buffer) { + try { + if(this.InputDisks[inputdisk].Length <= incount * this.Stripe * this.Sector) { + throw new OverflowException("EOF of " + this.InputDisks[inputdisk].Name + " reached"); + } + if(this.InputDisks[inputdisk].Length <= (incount * this.Stripe * this.Sector) + this.Sector) { + buffer.Clear(); + } + this.InputDisks[inputdisk].Seek(incount * this.Stripe * this.Sector, SeekOrigin.Begin); + this.InputDisks[inputdisk].Read(buffer); + } catch (Exception e) { + Console.WriteLine("Error while reading: " + this.InputDisks[inputdisk].Name); + Console.WriteLine(this.InputDisks[inputdisk].Name + " Seek(" + incount * this.Stripe * this.Sector + ", Begin)"); + Console.WriteLine(this.InputDisks[inputdisk].Name + " Read(" + buffer.Length + ", 0, " + (Int32)this.Sector + ")"); + throw e; + } + + try { + this.OutputDisk.Seek(outcount * this.Stripe * this.Sector, SeekOrigin.Begin); + this.OutputDisk.Write(buffer); + this.OutputDisk.Flush(); + } catch (Exception e) { + Console.WriteLine("Error while writing: " + this.OutputDisk.Name); + Console.WriteLine(this.OutputDisk.Name + "Seek(" + outcount * this.Stripe * this.Sector + ", Begin)"); + Console.WriteLine(this.OutputDisk.Name + " Write(" + buffer.Length + ", 0, " + (Int32)this.Sector + ")"); + Console.WriteLine(this.OutputDisk.Name + "Flush()"); + throw e; + } + + Console.WriteLine("["+Math.Round(((Double)outcount/4)*100, 3)+"] " + + "Copy disk" + (inputdisk + 1) + " " + + "[" + (incount * this.Stripe) + " s, " + ((incount + 1) * this.Stripe) + " s] " + + "(" + (incount * this.Stripe * this.Sector) + " b, " + ((incount + 1) * this.Stripe * this.Sector) + " b) " + + "-> out " + + "[" + (outcount * this.Stripe) + " s, " + ((outcount + 1) * this.Stripe) + " s] " + + "(" + (outcount * this.Stripe * this.Sector) + " b, " + ((outcount + 1) * this.Stripe * this.Sector) + " b)"); + } + } +} \ No newline at end of file diff --git a/hp-raid45-recovery/Program.cs b/hp-raid45-recovery/Program.cs new file mode 100644 index 0000000..76607df --- /dev/null +++ b/hp-raid45-recovery/Program.cs @@ -0,0 +1,155 @@ +using BlubbFish.Utils; +using System; +using System.Collections.Generic; +using System.IO; + +namespace BlubbFish.Tools.Raid.HP.Raid45 +{ + class Program + { + public Program(String[] args) { + CmdArgs.Instance.SetArguments(new Dictionary { + {"--disk1", new CmdArgs.VaildArguments(CmdArgs.ArgLength.Touple, true) }, + {"--disk2", new CmdArgs.VaildArguments(CmdArgs.ArgLength.Touple, true) }, + {"--disk3", new CmdArgs.VaildArguments(CmdArgs.ArgLength.Touple, true) }, + {"--disk4", new CmdArgs.VaildArguments(CmdArgs.ArgLength.Touple, true) }, + {"--out", new CmdArgs.VaildArguments(CmdArgs.ArgLength.Touple, true) }, + {"--sectorsize", new CmdArgs.VaildArguments(CmdArgs.ArgLength.Touple, false, "512", "Size in Byte of one Sector") }, + {"--stripesize", new CmdArgs.VaildArguments(CmdArgs.ArgLength.Touple, false, "128", "Size of a stripe in Sectors") }, + {"--paritysize", new CmdArgs.VaildArguments(CmdArgs.ArgLength.Touple, false, "16", "Ammount of stripes after we switch the parity device") }, + {"--start", new CmdArgs.VaildArguments(CmdArgs.ArgLength.Touple, false, "0", "Sector where we start") }, + {"--end", new CmdArgs.VaildArguments(CmdArgs.ArgLength.Touple, false, "0", + "End Sector where we stop read from one Disk.\n" + + "If 0 or not present, we read as long the input file goes.\n"+ + "\tIf we want read 1gb in total, \n" + + "\t1073741824 bytes / 512 bytes = 2097152 sectors\n" + + "\t2097152 sectors / 3 disks = ~699051") } + }, args); + + if(!this.DoChecks()) { + return; + } + + CopyProcess cp = new CopyProcess(); + cp.SetInputFiles( + CmdArgs.Instance.GetArgumentData("--disk1"), + CmdArgs.Instance.GetArgumentData("--disk2"), + CmdArgs.Instance.GetArgumentData("--disk3"), + CmdArgs.Instance.GetArgumentData("--disk4") + ); + cp.SetOutputFile(CmdArgs.Instance.GetArgumentData("--out")); + cp.SetParameters( + UInt32.Parse(CmdArgs.Instance.GetArgumentData("--sectorsize")), + UInt32.Parse(CmdArgs.Instance.GetArgumentData("--stripesize")), + UInt32.Parse(CmdArgs.Instance.GetArgumentData("--paritysize")) + ); + cp.SetStartEnd( + Int64.Parse(CmdArgs.Instance.GetArgumentData("--start")), + Int64.Parse(CmdArgs.Instance.GetArgumentData("--end")) + ); + cp.Running(); + } + + private Boolean DoChecks() { + if (!CmdArgs.Instance.HasAllRequiredArguments()) { + Console.WriteLine(CmdArgs.Instance.GetUsageList("Recovery.exe")); + return false; + } + + for (Int32 i = 1; i < 5; i++) { + if (!File.Exists(CmdArgs.Instance.GetArgumentData("--disk"+i))) { + Console.WriteLine("--disk" + i + " could not be found. [" + CmdArgs.Instance.GetArgumentData("--disk" + i) + "]"); + return false; + } + try { + FileStream f = File.OpenRead(CmdArgs.Instance.GetArgumentData("--disk" + i)); + f.ReadByte(); + f.Close(); + } catch (Exception e) { + Console.WriteLine("--disk" + i + " could not be open. [" + CmdArgs.Instance.GetArgumentData("--disk" + i) + "]\n\n" + e.Message); + return false; + } + Console.WriteLine("Using Disk " + i + " with \"" + CmdArgs.Instance.GetArgumentData("--disk" + i) + "\""); + } + + Console.WriteLine("Raid Aligment [Disks]"); + Console.WriteLine("---------------------"); + Console.WriteLine("| 1 | 2 | 3 | P |"); + Console.WriteLine("| 1 | 2 | P | 3 |"); + Console.WriteLine("| 1 | P | 2 | 3 |"); + Console.WriteLine("| P | 1 | 2 | 3 |"); + Console.WriteLine("---------------------"); + Console.WriteLine("Raid Aligment [Stripes #]"); + Console.WriteLine("---------------------"); + Console.WriteLine("| 1 | 2 | 3 | P |"); + Console.WriteLine("| 4 | 5 | P | 6 |"); + Console.WriteLine("| 7 | P | 8 | 9 |"); + Console.WriteLine("| P | 10 | 11 | 12 |"); + Console.WriteLine("---------------------"); + + Console.WriteLine("Using Output with \"" + CmdArgs.Instance.GetArgumentData("--out") + "\""); + if (File.Exists(CmdArgs.Instance.GetArgumentData("--out"))) { + Console.WriteLine("ATTENTIONE ATTENTIONE!!!!!!!:\n" + + "The target existing, if you shure to overwrite this file press [y] to continue.\n" + + "Every other key will exit the programm!"); + if (Console.ReadKey().Key != ConsoleKey.Y) { + return false; + } + Console.WriteLine("You want it you have it!"); + } + + try { + FileStream f = File.OpenWrite(CmdArgs.Instance.GetArgumentData("--out")); + f.WriteByte((Byte)'A'); + f.Close(); + } catch (Exception e) { + Console.WriteLine("--out could not be written. [" + CmdArgs.Instance.GetArgumentData("--out") + "]\n\n" + e.Message); + return false; + } + + if (!UInt32.TryParse(CmdArgs.Instance.GetArgumentData("--sectorsize"), out UInt32 sectorsize)) { + Console.WriteLine("--sectorsize must be an UInt32"); + return false; + } else { + Console.WriteLine("Sector Size: " + sectorsize); + } + + if (!UInt32.TryParse(CmdArgs.Instance.GetArgumentData("--stripesize"), out UInt32 stripesize)) { + Console.WriteLine("--stripesize must be an UInt32"); + return false; + } else { + Console.WriteLine("Stripe Size: " + stripesize); + } + + if (!UInt32.TryParse(CmdArgs.Instance.GetArgumentData("--paritysize"), out UInt32 paritysize)) { + Console.WriteLine("--paritysize must be an UInt32"); + return false; + } else { + Console.WriteLine("Parity Size: " + paritysize); + } + + if (!Int64.TryParse(CmdArgs.Instance.GetArgumentData("--start"), out Int64 start)) { + Console.WriteLine("--start must be an UInt64"); + return false; + } else { + Console.WriteLine("Startsector: " + start); + } + + if (!Int64.TryParse(CmdArgs.Instance.GetArgumentData("--end"), out Int64 end)) { + Console.WriteLine("--end must be an UInt64"); + return false; + } else { + Console.WriteLine("Endsector: " + end); + } + + + Console.WriteLine("-------------------------------------------------------------------------------"); + Console.WriteLine("Press [return] to Start."); + Console.ReadLine(); + Console.WriteLine("-------------------------------------------------------------------------------"); + return true; + } + + static void Main(String[] args) => new Program(args); + } +} diff --git a/hp-raid45-recovery/Properties/launchSettings.json b/hp-raid45-recovery/Properties/launchSettings.json new file mode 100644 index 0000000..a10b324 --- /dev/null +++ b/hp-raid45-recovery/Properties/launchSettings.json @@ -0,0 +1,8 @@ +{ + "profiles": { + "hp-raid45-recovery": { + "commandName": "Project", + "commandLineArgs": "--disk1 G:\\img\\disk1.img --disk2 G:\\img\\disk2.img --disk3 G:\\img\\disk3.img --disk4 G:\\img\\disk4.img --start 4 --end 8 --out G:\\img\\test.img --paritysize 1 --sectorsize 4 --stripesize 1" + } + } +} \ No newline at end of file diff --git a/hp-raid45-recovery/hp-raid45-recovery.csproj b/hp-raid45-recovery/hp-raid45-recovery.csproj new file mode 100644 index 0000000..9f81e4e --- /dev/null +++ b/hp-raid45-recovery/hp-raid45-recovery.csproj @@ -0,0 +1,14 @@ + + + + Exe + netcoreapp3.1 + BlubbFish.Tools.Raid.HP.Raid45 + Recovery + + + + + + +