GDROMExplorer/SEGATools/DiscFileSystem/DiscFileSystemBuilder.cs

162 lines
6.7 KiB
C#

// Decompiled with JetBrains decompiler
// Type: SEGATools.DiscFileSystem.DiscFileSystemBuilder
// Assembly: SEGATools, Version=1.0.3.0, Culture=neutral, PublicKeyToken=611be24fdeb07e08
// MVID: D631183F-57B1-40A1-B502-5364D288307A
// Assembly location: SEGATools.dll
using ImageReader.DiscFileSystem;
using ImageReader.ImageReader;
using ImageReader.ISO9660.DirectoryRecords;
using ImageReader.Stream;
using SEGATools.Encrypt;
using SEGATools.Security;
using System;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace SEGATools.DiscFileSystem
{
public sealed class DiscFileSystemBuilder
{
private static readonly Logger.ILog logger = Logger.CreateLog();
private static readonly string NAOMI_GD_BINARY_NAME = "NAOMIGD.BIN";
private static readonly Regex NAOMI_PRODUCT_ID_PREFIX = new Regex("GD.+-.*", RegexOptions.IgnoreCase | RegexOptions.Compiled);
private static readonly string NAOMI_KEY_FILE_EXT = "key";
private static readonly string NAOMI_KEY_FILE_NAME = "key.txt";
private static InitialProgram GetBootStrapFrom(IDiscTrack track)
{
byte[] buffer;
using (DiscSectorStream discSectorStream = new DiscSectorStream(track.FileInputStream, track.TrackSector, 0U, InitialProgram.IP_FILESIZE, true))
{
buffer = new byte[discSectorStream.Length];
discSectorStream.Read(buffer, 0, buffer.Length);
}
try
{
return InitialProgramConverter.ToInitialProgram(buffer, 0);
}
catch (InitialProgramInvalidHardwareIdException ex)
{
logger.Warn(ex);
return (InitialProgram) null;
}
finally
{
}
}
private static InitialProgram GetBootStrapFrom(IDiscSession session)
{
foreach (IDiscTrack dataTrack in session.DataTracks)
{
InitialProgram bootStrapFrom = DiscFileSystemBuilder.GetBootStrapFrom(dataTrack);
if (bootStrapFrom != null)
return bootStrapFrom;
}
return (InitialProgram) null;
}
private static DirectoryRecord GetMainBinary(
IDiscFileSystem discFileSystem,
DirectoryRecord rootDirectoryRecord,
InitialProgram ip)
{
if (rootDirectoryRecord.Contains(DiscFileSystemBuilder.NAOMI_GD_BINARY_NAME))
{
DirectoryRecord directoryRecord1 = rootDirectoryRecord.SubDirectories.Find((Predicate<DirectoryRecord>) (directoryRecord => directoryRecord.ExtentSize.Equals(256U)));
DiscSectorStream forDirectoryRecord = discFileSystem.GetDiscStreamForDirectoryRecord(directoryRecord1);
forDirectoryRecord.Seek(192L, SeekOrigin.Begin);
byte[] numArray = new byte[64];
forDirectoryRecord.Read(numArray, 0, numArray.Length);
int count = 0;
while (count < numArray.Length && numArray[count] != (byte) 0)
++count;
string NaomiMainBinaryFileName = Encoding.Default.GetString(numArray, 0, count);
return rootDirectoryRecord.SubDirectories.Find((Predicate<DirectoryRecord>) (directoryRecord => directoryRecord.Name.Equals(NaomiMainBinaryFileName)));
}
string MainBinaryFileName = ip.MainBinary.Trim();
return rootDirectoryRecord.Contains(MainBinaryFileName) ? rootDirectoryRecord.SubDirectories.Find((Predicate<DirectoryRecord>) (directoryRecord => directoryRecord.Name.Equals(MainBinaryFileName))) : (DirectoryRecord) null;
}
private static DESKey TryGetDESKey(string FileName)
{
string[] strArray = new string[2]
{
Path.ChangeExtension(FileName, DiscFileSystemBuilder.NAOMI_KEY_FILE_EXT),
Path.Combine(Path.GetDirectoryName(FileName), DiscFileSystemBuilder.NAOMI_KEY_FILE_NAME)
};
foreach (string path in strArray)
{
DiscFileSystemBuilder.logger.DebugFormat("Searching for DES key in {0}", (object) path);
if (File.Exists(path))
{
using (StreamReader streamReader = new StreamReader(path))
{
string key = streamReader.ReadLine();
if (DESKey.TryParse(key))
{
DESKey desKey = DESKey.Parse(key);
DiscFileSystemBuilder.logger.DebugFormat("DESKey found in {0}: {1}", (object) path, (object) desKey);
return desKey;
}
DiscFileSystemBuilder.logger.WarnFormat("Could not parse the DES key in {0}", (object) path);
}
}
}
DiscFileSystemBuilder.logger.Debug((object) "No DES key found");
return (DESKey) null;
}
public static IDiscFileSystem ToDisc(
string FileName,
IDiscFileSystemConverter DiscFileSystemConverter,
bool computePathTable)
{
IDiscFileSystem discFileSystem = DiscFileSystemConverter.ToDiscFileSystem(FileName);
foreach (IDiscSession session in discFileSystem.Sessions.FindAll((Predicate<IDiscSession>) (s => s.DataTracks.Count > 0)))
{
if (session.DataTracks.Count >= 1)
{
IDiscTrack dataTrack = session.DataTracks[0];
try
{
using (DiscImageReader discImageReader = new DiscImageReader())
{
discImageReader.ParsePathTable = !computePathTable;
discImageReader.Open(dataTrack.FileInputStream, dataTrack.LogicalBlockAddress, dataTrack.TrackSector);
session.PrimaryVolumeDescriptor = discImageReader.PrimaryVolumeDescriptor;
session.RootDirectoryRecord = discImageReader.PrimaryVolumeDescriptor.RootDirectoryRecord;
}
}
catch (DiscImageReaderException ex)
{
logger.Error(ex);
}
}
session.BootStrap = DiscFileSystemBuilder.GetBootStrapFrom(session);
}
IDiscSession discSession1 = discFileSystem.Sessions.LastOrDefault<IDiscSession>((Func<IDiscSession, bool>) (session => session.RootDirectoryRecord != null));
if (discSession1 == null)
throw DiscFileSystemException.noFileSystemFoundException();
IDiscSession discSession2 = discFileSystem.Sessions.LastOrDefault<IDiscSession>((Func<IDiscSession, bool>) (s => s.BootStrap != null));
if (discSession2 != null && discSession2.BootStrap != null)
{
discFileSystem.DiscType = DiscImageType.Dreamcast;
InitialProgram bootStrap = discSession2.BootStrap;
discSession1.MainBinary = DiscFileSystemBuilder.GetMainBinary(discFileSystem, discSession1.RootDirectoryRecord, bootStrap);
if (DiscFileSystemBuilder.NAOMI_PRODUCT_ID_PREFIX.Match(bootStrap.ProductID).Success)
{
discFileSystem.DiscType = DiscImageType.Naomi;
discFileSystem.NaomiDESKey = DiscFileSystemBuilder.TryGetDESKey(FileName);
}
discFileSystem.DiscName = bootStrap.SoftwareName.Trim();
discFileSystem.MainBinary = discSession1.MainBinary;
}
return discFileSystem;
}
}
}