mirror of
https://github.com/SabreTools/MPF.git
synced 2026-07-02 17:24:48 +00:00
Add INI parser, use for PS1/2 discs
This commit is contained in:
@@ -2417,7 +2417,7 @@ namespace DICUI.DiscImageCreator
|
||||
/// <param name="region">Output region, if possible</param>
|
||||
/// <param name="date">Output EXE date in "yyyy-mm-dd" format if possible, null on error</param>
|
||||
/// <returns></returns>
|
||||
private static bool GetPlaystationExecutableInfo(char? driveLetter, out Region? region, out string date)
|
||||
public static bool GetPlaystationExecutableInfo(char? driveLetter, out Region? region, out string date)
|
||||
{
|
||||
region = null; date = null;
|
||||
|
||||
@@ -2437,31 +2437,26 @@ namespace DICUI.DiscImageCreator
|
||||
// Try both of the common paths that contain information
|
||||
string exeName = null;
|
||||
|
||||
// Try reading SYSTEM.CNF to find the "BOOT" value
|
||||
if (File.Exists(systemCnfPath))
|
||||
{
|
||||
try
|
||||
{
|
||||
using (StreamReader sr = File.OpenText(systemCnfPath))
|
||||
{
|
||||
// Not assuming any ordering, just in case
|
||||
string line = sr.ReadLine();
|
||||
while (!line.StartsWith("BOOT"))
|
||||
line = sr.ReadLine();
|
||||
// Read the CNF file as an INI file
|
||||
var keyValuePairs = IniParse.ParseIniFile(systemCnfPath);
|
||||
string bootValue = string.Empty;
|
||||
|
||||
// Once it finds the "BOOT" line, extract the name, if possible
|
||||
var match = Regex.Match(line, @"BOOT.*?=\s*cdrom.?:\\?(.*?)");
|
||||
if (match != null && match.Groups.Count > 1)
|
||||
{
|
||||
exeName = match.Groups[1].Value;
|
||||
exeName = exeName.Split(';')[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
// PlayStation uses "BOOT" as the key
|
||||
if (keyValuePairs.ContainsKey("boot"))
|
||||
bootValue = keyValuePairs["boot"];
|
||||
|
||||
// PlayStation 2 uses "BOOT2" as the key
|
||||
if (keyValuePairs.ContainsKey("boot2"))
|
||||
bootValue = keyValuePairs["boot2"];
|
||||
|
||||
// If we had any boot value, parse it and get the executable name
|
||||
if (!string.IsNullOrEmpty(bootValue))
|
||||
{
|
||||
var match = Regex.Match(bootValue, @"cdrom.?:\\?(.*)");
|
||||
if (match != null && match.Groups.Count > 1)
|
||||
{
|
||||
// We don't care what the error was
|
||||
return false;
|
||||
exeName = match.Groups[1].Value;
|
||||
exeName = exeName.Split(';')[0];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2555,34 +2550,16 @@ namespace DICUI.DiscImageCreator
|
||||
if (!Directory.Exists(drivePath))
|
||||
return null;
|
||||
|
||||
// If we can't find SYSTEM.CNF, we don't have a PlayStation 2 disc
|
||||
// Get the SYSTEM.CNF path to check
|
||||
string systemCnfPath = Path.Combine(drivePath, "SYSTEM.CNF");
|
||||
if (!File.Exists(systemCnfPath))
|
||||
return null;
|
||||
|
||||
// Try reading SYSTEM.CNF to find the "VER" value
|
||||
try
|
||||
{
|
||||
using (StreamReader sr = File.OpenText(systemCnfPath))
|
||||
{
|
||||
// Not assuming proper ordering, just in case
|
||||
string line = sr.ReadLine();
|
||||
while (!line.StartsWith("VER"))
|
||||
line = sr.ReadLine();
|
||||
|
||||
// Once it finds the "VER" line, extract the version
|
||||
var match = Regex.Match(line, @"VER\s*=\s*(.*)");
|
||||
if (match != null && match.Groups.Count > 1)
|
||||
return match.Groups[1].Value;
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// We don't care what the error was
|
||||
return null;
|
||||
}
|
||||
// Try to parse the SYSTEM.CNF file
|
||||
var keyValuePairs = IniParse.ParseIniFile(systemCnfPath);
|
||||
if (keyValuePairs.ContainsKey("ver"))
|
||||
return keyValuePairs["ver"];
|
||||
|
||||
// If "VER" can't be found, we can't do much
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
91
DICUI.Library/Utilities/IniParse.cs
Normal file
91
DICUI.Library/Utilities/IniParse.cs
Normal file
@@ -0,0 +1,91 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace DICUI.Utilities
|
||||
{
|
||||
public static class IniParse
|
||||
{
|
||||
/// <summary>
|
||||
/// Read an INI file based on the path
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
/// <returns></returns>
|
||||
public static Dictionary<string, string> ParseIniFile(string path)
|
||||
{
|
||||
// If we don't have a file, we can't read it
|
||||
if (!File.Exists(path))
|
||||
return new Dictionary<string, string>();
|
||||
|
||||
using (var fileStream = File.OpenRead(path))
|
||||
{
|
||||
return ParseIniFile(fileStream);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read an INI file from a stream
|
||||
/// </summary>
|
||||
/// <param name="stream"></param>
|
||||
/// <returns></returns>
|
||||
public static Dictionary<string, string> ParseIniFile(Stream stream)
|
||||
{
|
||||
// If the stream is invalid or unreadable, we can't process it
|
||||
if (stream == null || !stream.CanRead || stream.Position >= stream.Length - 1)
|
||||
return new Dictionary<string, string>();
|
||||
|
||||
// Keys are case-insensitive by default
|
||||
var keyValuePairs = new Dictionary<string, string>();
|
||||
try
|
||||
{
|
||||
using (StreamReader sr = new StreamReader(stream))
|
||||
{
|
||||
string section = string.Empty;
|
||||
while (!sr.EndOfStream)
|
||||
{
|
||||
string line = sr.ReadLine().Trim();
|
||||
|
||||
// Comments start with ';'
|
||||
if (line.StartsWith(";"))
|
||||
{
|
||||
// No-op, we don't process comments
|
||||
}
|
||||
|
||||
// Section titles are surrounded by square brackets
|
||||
else if (line.StartsWith("["))
|
||||
{
|
||||
section = line.TrimStart('[').TrimEnd(']');
|
||||
}
|
||||
|
||||
// Valid INI lines are in the format key=value
|
||||
else if (line.Contains("="))
|
||||
{
|
||||
// Split the line by '=' for key-value pairs
|
||||
string[] data = line.Split('=');
|
||||
|
||||
// If the value field contains an '=', we need to put them back in
|
||||
string key = data[0].Trim();
|
||||
string value = string.Join("=", data.Skip(1)).Trim();
|
||||
|
||||
// Section names are prepended to the key with a '.' separating
|
||||
if (!string.IsNullOrEmpty(section))
|
||||
key = $"{section}.{key}";
|
||||
|
||||
// Set or overwrite keys in the returned dictionary
|
||||
keyValuePairs[key.ToLowerInvariant()] = value;
|
||||
}
|
||||
|
||||
// All other lines are ignored
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// We don't care what the error was, just catch and return
|
||||
return new Dictionary<string, string>();
|
||||
}
|
||||
|
||||
return keyValuePairs;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user