// Spludlow Software // Copyright © Samuel P. Ludlow 2020 All Rights Reserved // Distributed under the terms of the GNU General Public License version 3 // Distributed WITHOUT ANY WARRANTY; without implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE // https://www.spludlow.co.uk/LICENCE.TXT // The Spludlow logo is a registered trademark of Samuel P. Ludlow and may not be used without permission // v1.14 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.IO; namespace Spludlow.Mame { public class MameChdMan { private int TimeOutSeconds = 60 * 60; // 1h private string ChdManPath; public MameChdMan() { MameConfiguration config = new MameConfiguration(); Start(config.BinariesDirectory); } public MameChdMan(string mameBinariesPath) { Start(mameBinariesPath); } private void Start(string mameBinariesPath) { ChdManPath = mameBinariesPath + @"\chdman.exe"; if (File.Exists(ChdManPath) == false) throw new ApplicationException("MameChdMan, Program not found: " + ChdManPath); } public string Hash(string filename) { Dictionary info = Info(filename); string sha1 = ""; if (info.ContainsKey("SHA1") == true) sha1 = info["SHA1"]; if (sha1.Length != 40) throw new ApplicationException("MameChdMan, hash not found in output: " + filename); return sha1.ToUpper(); } public Dictionary Info(string filename) { return ParseResult(Run("info -i \"" + filename + "\"")); } public string Run(string arguments) { return Run(arguments, ChdManPath, null); } public string Run(string arguments, string chdmanPath, string directory) { if (File.Exists(chdmanPath) == false) throw new ApplicationException("chdman not found: " + chdmanPath); Spludlow.SpawnProcess.ProcessExitInfo info = Spludlow.SpawnProcess.Run(chdmanPath, arguments, directory, null, TimeOutSeconds, false); // Can output to stderr when no err (verify) if (info.ExitCode != 0) { Spludlow.Log.Error("MameChdMan, exit: " + info.ExitCode, "ERR: " + info.StandardError + Environment.NewLine + "OUT:" + info.StandardOutput); throw new ApplicationException("CHD Man bad exit code: " + info.ExitCode + ", " + info.StandardError); } return info.StandardOutput; } public static Dictionary ParseResult(string text) { Dictionary result = new Dictionary(); using (StringReader reader = new StringReader(text)) { string line; while ((line = reader.ReadLine()) != null) { int index = line.IndexOf(":"); if (index == -1) continue; string key = line.Substring(0, index).Trim(); string value = line.Substring(index + 1).Trim(); if (result.ContainsKey(key) == true) { int count = 2; while (result.ContainsKey(key + count) == true) { ++count; } key = key + count; } result.Add(key, value); } } return result; } public bool Verify(string filename) { string output = VerifyRaw(filename); bool result = VerifyOutput(output); if (result == false) Spludlow.Log.Warning("ChdMan Verify Fail: " + filename, output); return result; } public string VerifyRaw(string filename) { return Run("verify -i \"" + filename + "\""); } public bool VerifyOutput(string output) { if (output.Contains("Raw SHA1 verification successful!") == true && output.Contains("Overall SHA1 verification successful!") == true) { return true; } return false; } } }