162 lines
6.7 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|