initial commit
This commit is contained in:
commit
1b60743303
274 changed files with 25866 additions and 0 deletions
113
SEGATools/DiscFileSystem/DiscFileSystem.cs
Normal file
113
SEGATools/DiscFileSystem/DiscFileSystem.cs
Normal file
|
@ -0,0 +1,113 @@
|
|||
// Decompiled with JetBrains decompiler
|
||||
// Type: SEGATools.DiscFileSystem.DiscFileSystem
|
||||
// Assembly: SEGATools, Version=1.0.3.0, Culture=neutral, PublicKeyToken=611be24fdeb07e08
|
||||
// MVID: D631183F-57B1-40A1-B502-5364D288307A
|
||||
// Assembly location: SEGATools.dll
|
||||
|
||||
using ImageReader.ISO9660.DirectoryRecords;
|
||||
using ImageReader.Stream;
|
||||
using SEGATools.Binary;
|
||||
using SEGATools.Encrypt;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace SEGATools.DiscFileSystem
|
||||
{
|
||||
internal sealed class DiscFileSystem : IDiscFileSystem
|
||||
{
|
||||
private readonly Dictionary<object, List<SEGALibrary>> FileLibraries;
|
||||
|
||||
public List<IDiscSession> Sessions { get; private set; }
|
||||
|
||||
public string FileName { get; private set; }
|
||||
|
||||
public bool CanExtractData { get; private set; }
|
||||
|
||||
public bool CanBeExportedToCueSheet { get; private set; }
|
||||
|
||||
public bool CanBeExportedToGdi { get; private set; }
|
||||
|
||||
public string DiscName { get; set; }
|
||||
|
||||
public DirectoryRecord MainBinary { get; set; }
|
||||
|
||||
public DiscImageType DiscType { get; set; }
|
||||
|
||||
public List<IDiscTrack> AllTracks
|
||||
{
|
||||
get
|
||||
{
|
||||
List<IDiscTrack> allTracks = new List<IDiscTrack>();
|
||||
this.Sessions.ForEach((Action<IDiscSession>) (session => allTracks.AddRange((IEnumerable<IDiscTrack>) session.Tracks)));
|
||||
return allTracks.OrderBy<IDiscTrack, uint>((Func<IDiscTrack, uint>) (track => track.LogicalBlockAddress)).ToList<IDiscTrack>();
|
||||
}
|
||||
}
|
||||
|
||||
public DESKey NaomiDESKey { get; set; }
|
||||
|
||||
internal DiscFileSystem(string filename, List<IDiscSession> sessions)
|
||||
: this(filename, sessions, false, false, false)
|
||||
{
|
||||
}
|
||||
|
||||
internal DiscFileSystem(
|
||||
string filename,
|
||||
List<IDiscSession> sessions,
|
||||
bool supportDataExtraction)
|
||||
: this(filename, sessions, supportDataExtraction, false, false)
|
||||
{
|
||||
}
|
||||
|
||||
internal DiscFileSystem(
|
||||
string filename,
|
||||
List<IDiscSession> sessions,
|
||||
bool supportDataExtraction,
|
||||
bool supportCueSheet)
|
||||
: this(filename, sessions, supportDataExtraction, supportCueSheet, false)
|
||||
{
|
||||
}
|
||||
|
||||
internal DiscFileSystem(
|
||||
string filename,
|
||||
List<IDiscSession> sessions,
|
||||
bool supportDataExtraction,
|
||||
bool supportCueSheet,
|
||||
bool supportGdiExport)
|
||||
{
|
||||
this.FileName = filename;
|
||||
this.DiscName = "N/A";
|
||||
sessions.ForEach((Action<IDiscSession>) (discSession => discSession.Disc = (IDiscFileSystem) this));
|
||||
this.Sessions = sessions.OrderBy<IDiscSession, int>((Func<IDiscSession, int>) (session => session.Index)).ToList<IDiscSession>();
|
||||
this.DiscType = DiscImageType.Unknown;
|
||||
this.CanExtractData = supportDataExtraction;
|
||||
this.CanBeExportedToCueSheet = supportCueSheet;
|
||||
this.CanBeExportedToGdi = supportGdiExport;
|
||||
this.FileLibraries = new Dictionary<object, List<SEGALibrary>>();
|
||||
}
|
||||
|
||||
public IDiscTrack GetTrackForLogicalBlockAddress(long lba) => this.AllTracks.LastOrDefault<IDiscTrack>((Func<IDiscTrack, bool>) (track => (long) track.LogicalBlockAddress <= lba));
|
||||
|
||||
public DiscSectorStream GetDiscStreamForDirectoryRecord(
|
||||
DirectoryRecord directoryRecord)
|
||||
{
|
||||
IDiscTrack logicalBlockAddress = this.GetTrackForLogicalBlockAddress((long) directoryRecord.Extent);
|
||||
return logicalBlockAddress == null || directoryRecord.IsDirectory ? (DiscSectorStream) null : new DiscSectorStream(logicalBlockAddress.FileInputStream, logicalBlockAddress.TrackSector, directoryRecord.Extent - logicalBlockAddress.LogicalBlockAddress, directoryRecord.ExtentSize, true);
|
||||
}
|
||||
|
||||
public void RegisterLibraries(object file, List<SEGALibrary> Libraries) => this.FileLibraries[file] = Libraries;
|
||||
|
||||
public List<SEGALibrary> GetSEGALibraries(object file) => !this.FileLibraries.Keys.Contains<object>(file) ? (List<SEGALibrary>) null : this.FileLibraries[file];
|
||||
|
||||
public void Close()
|
||||
{
|
||||
this.MainBinary = (DirectoryRecord) null;
|
||||
if (this.Sessions == null)
|
||||
return;
|
||||
foreach (IDiscSession session in this.Sessions)
|
||||
session.Close();
|
||||
this.Sessions.Clear();
|
||||
this.Sessions = (List<IDiscSession>) null;
|
||||
}
|
||||
}
|
||||
}
|
161
SEGATools/DiscFileSystem/DiscFileSystemBuilder.cs
Normal file
161
SEGATools/DiscFileSystem/DiscFileSystemBuilder.cs
Normal file
|
@ -0,0 +1,161 @@
|
|||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
20
SEGATools/DiscFileSystem/DiscFileUtils.cs
Normal file
20
SEGATools/DiscFileSystem/DiscFileUtils.cs
Normal file
|
@ -0,0 +1,20 @@
|
|||
// Decompiled with JetBrains decompiler
|
||||
// Type: SEGATools.DiscFileSystem.DiscFileUtils
|
||||
// Assembly: SEGATools, Version=1.0.3.0, Culture=neutral, PublicKeyToken=611be24fdeb07e08
|
||||
// MVID: D631183F-57B1-40A1-B502-5364D288307A
|
||||
// Assembly location: SEGATools.dll
|
||||
|
||||
using ImageReader.DiscSectors;
|
||||
|
||||
namespace SEGATools.DiscFileSystem
|
||||
{
|
||||
public class DiscFileUtils
|
||||
{
|
||||
public static string GetExtensionForDiscTrack(IDiscTrack DiscTrack)
|
||||
{
|
||||
if (DiscTrack.TrackData == TrackModeType.Audio)
|
||||
return ".raw";
|
||||
return DiscTrack.TrackSector is ISO9660Sector ? ".iso" : ".bin";
|
||||
}
|
||||
}
|
||||
}
|
23
SEGATools/DiscFileSystem/DiscFormatException.cs
Normal file
23
SEGATools/DiscFileSystem/DiscFormatException.cs
Normal file
|
@ -0,0 +1,23 @@
|
|||
// Decompiled with JetBrains decompiler
|
||||
// Type: SEGATools.DiscFileSystem.DiscFormatException
|
||||
// Assembly: SEGATools, Version=1.0.3.0, Culture=neutral, PublicKeyToken=611be24fdeb07e08
|
||||
// MVID: D631183F-57B1-40A1-B502-5364D288307A
|
||||
// Assembly location: SEGATools.dll
|
||||
|
||||
using System;
|
||||
|
||||
namespace SEGATools.DiscFileSystem
|
||||
{
|
||||
public class DiscFormatException : Exception
|
||||
{
|
||||
public DiscFormatException(string message)
|
||||
: base(message)
|
||||
{
|
||||
}
|
||||
|
||||
public DiscFormatException(string message, Exception innerException)
|
||||
: base(message, innerException)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
15
SEGATools/DiscFileSystem/DiscImageType.cs
Normal file
15
SEGATools/DiscFileSystem/DiscImageType.cs
Normal file
|
@ -0,0 +1,15 @@
|
|||
// Decompiled with JetBrains decompiler
|
||||
// Type: SEGATools.DiscFileSystem.DiscImageType
|
||||
// Assembly: SEGATools, Version=1.0.3.0, Culture=neutral, PublicKeyToken=611be24fdeb07e08
|
||||
// MVID: D631183F-57B1-40A1-B502-5364D288307A
|
||||
// Assembly location: SEGATools.dll
|
||||
|
||||
namespace SEGATools.DiscFileSystem
|
||||
{
|
||||
public enum DiscImageType : short
|
||||
{
|
||||
Unknown,
|
||||
Dreamcast,
|
||||
Naomi,
|
||||
}
|
||||
}
|
110
SEGATools/DiscFileSystem/DiscSession.cs
Normal file
110
SEGATools/DiscFileSystem/DiscSession.cs
Normal file
|
@ -0,0 +1,110 @@
|
|||
// Decompiled with JetBrains decompiler
|
||||
// Type: SEGATools.DiscFileSystem.DiscSession
|
||||
// Assembly: SEGATools, Version=1.0.3.0, Culture=neutral, PublicKeyToken=611be24fdeb07e08
|
||||
// MVID: D631183F-57B1-40A1-B502-5364D288307A
|
||||
// Assembly location: SEGATools.dll
|
||||
|
||||
using ImageReader.ISO9660.DirectoryRecords;
|
||||
using ImageReader.ISO9660.VolumeDescriptors;
|
||||
using SEGATools.Security;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace SEGATools.DiscFileSystem
|
||||
{
|
||||
internal sealed class DiscSession : IDiscSession
|
||||
{
|
||||
public static readonly string DEFAULT_SESSION_NAME_WITH_FORMAT = "Session {0}";
|
||||
private readonly string name;
|
||||
private int index;
|
||||
private InitialProgram ip;
|
||||
private IDiscFileSystem disc;
|
||||
private DirectoryRecord mainBinary;
|
||||
private PrimaryVolumeDescriptor primaryVolumeDescriptor;
|
||||
private DirectoryRecord rootDirectoryRecord;
|
||||
private List<IDiscTrack> tracks;
|
||||
|
||||
public List<IDiscTrack> Tracks => this.tracks.ToList<IDiscTrack>();
|
||||
|
||||
public List<IDiscTrack> DataTracks => this.tracks.FindAll((Predicate<IDiscTrack>) (track => track.TrackData == TrackModeType.Data));
|
||||
|
||||
public IDiscTrack FirstDataTrack
|
||||
{
|
||||
get
|
||||
{
|
||||
List<IDiscTrack> all = this.tracks.FindAll((Predicate<IDiscTrack>) (track => track.TrackData == TrackModeType.Data));
|
||||
return all.Count <= 0 ? (IDiscTrack) null : all.OrderBy<IDiscTrack, int>((Func<IDiscTrack, int>) (track => track.Index)).First<IDiscTrack>();
|
||||
}
|
||||
}
|
||||
|
||||
public IDiscTrack LastDataTrack
|
||||
{
|
||||
get
|
||||
{
|
||||
List<IDiscTrack> all = this.tracks.FindAll((Predicate<IDiscTrack>) (track => track.TrackData == TrackModeType.Data));
|
||||
return all.Count <= 0 ? (IDiscTrack) null : all.OrderBy<IDiscTrack, int>((Func<IDiscTrack, int>) (track => track.Index)).Last<IDiscTrack>();
|
||||
}
|
||||
}
|
||||
|
||||
public List<IDiscTrack> AudioTracks => this.tracks.FindAll((Predicate<IDiscTrack>) (track => track.TrackData == TrackModeType.Audio));
|
||||
|
||||
public int Index => this.index;
|
||||
|
||||
public string Name => this.name;
|
||||
|
||||
public DirectoryRecord MainBinary
|
||||
{
|
||||
get => this.mainBinary;
|
||||
set => this.mainBinary = value;
|
||||
}
|
||||
|
||||
public DirectoryRecord RootDirectoryRecord
|
||||
{
|
||||
get => this.rootDirectoryRecord;
|
||||
set => this.rootDirectoryRecord = value;
|
||||
}
|
||||
|
||||
public InitialProgram BootStrap
|
||||
{
|
||||
get => this.ip;
|
||||
set => this.ip = value;
|
||||
}
|
||||
|
||||
public PrimaryVolumeDescriptor PrimaryVolumeDescriptor
|
||||
{
|
||||
get => this.primaryVolumeDescriptor;
|
||||
set => this.primaryVolumeDescriptor = value;
|
||||
}
|
||||
|
||||
public IDiscFileSystem Disc
|
||||
{
|
||||
get => this.disc;
|
||||
set => this.disc = value;
|
||||
}
|
||||
|
||||
public DiscSession(int index, string name, List<IDiscTrack> tracks)
|
||||
{
|
||||
this.index = index;
|
||||
this.name = name;
|
||||
this.tracks = tracks.OrderBy<IDiscTrack, uint>((Func<IDiscTrack, uint>) (track => track.LogicalBlockAddress)).ToList<IDiscTrack>();
|
||||
this.tracks.ForEach((Action<IDiscTrack>) (track => track.Session = (IDiscSession) this));
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
this.ip = (InitialProgram) null;
|
||||
this.mainBinary = (DirectoryRecord) null;
|
||||
this.rootDirectoryRecord = (DirectoryRecord) null;
|
||||
this.primaryVolumeDescriptor = (PrimaryVolumeDescriptor) null;
|
||||
if (this.tracks != null)
|
||||
{
|
||||
foreach (IDiscTrack track in this.tracks)
|
||||
track.Close();
|
||||
this.tracks.Clear();
|
||||
this.tracks = (List<IDiscTrack>) null;
|
||||
}
|
||||
this.disc = (IDiscFileSystem) null;
|
||||
}
|
||||
}
|
||||
}
|
87
SEGATools/DiscFileSystem/DiscTrack.cs
Normal file
87
SEGATools/DiscFileSystem/DiscTrack.cs
Normal file
|
@ -0,0 +1,87 @@
|
|||
// Decompiled with JetBrains decompiler
|
||||
// Type: SEGATools.DiscFileSystem.DiscTrack
|
||||
// Assembly: SEGATools, Version=1.0.3.0, Culture=neutral, PublicKeyToken=611be24fdeb07e08
|
||||
// MVID: D631183F-57B1-40A1-B502-5364D288307A
|
||||
// Assembly location: SEGATools.dll
|
||||
|
||||
using ImageReader.DiscSectors;
|
||||
using SEGATools.Stream;
|
||||
using SEGATools.VirtualFile;
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace SEGATools.DiscFileSystem
|
||||
{
|
||||
internal sealed class DiscTrack : IDiscTrack, IVirtualFile, IDisposable
|
||||
{
|
||||
private static readonly Logger.ILog logger = Logger.CreateLog();
|
||||
private bool disposed;
|
||||
|
||||
public string FileName { get; private set; }
|
||||
|
||||
public string Name => string.Format("Track {0:00}", (object) this.Index);
|
||||
|
||||
public int Index { get; private set; }
|
||||
|
||||
public uint LogicalBlockAddress { get; private set; }
|
||||
|
||||
public long Length { get; private set; }
|
||||
|
||||
public long Offset { get; private set; }
|
||||
|
||||
public TrackModeType TrackData { get; private set; }
|
||||
|
||||
public IDiscSector TrackSector { get; private set; }
|
||||
|
||||
public IDiscSession Session { get; set; }
|
||||
|
||||
public static IDiscTrack CreateCopyFrom(IDiscTrack source, string newFileName) => (IDiscTrack) new DiscTrack(newFileName, source.Offset, source.Length, source.LogicalBlockAddress, source.Index, source.TrackData, source.TrackSector);
|
||||
|
||||
internal DiscTrack(
|
||||
string fileName,
|
||||
long offset,
|
||||
long length,
|
||||
uint logicalBlockAdress,
|
||||
int index,
|
||||
TrackModeType trackData,
|
||||
IDiscSector trackSector)
|
||||
{
|
||||
this.disposed = false;
|
||||
this.LogicalBlockAddress = logicalBlockAdress;
|
||||
this.FileName = Path.GetFullPath(fileName);
|
||||
this.OriginalFileName = fileName;
|
||||
this.Index = index;
|
||||
this.TrackData = trackData;
|
||||
this.Offset = offset;
|
||||
this.Length = length;
|
||||
this.TrackSector = trackSector;
|
||||
}
|
||||
|
||||
public void Close() => this.Session = (IDiscSession) null;
|
||||
|
||||
public override string ToString() => this.Name;
|
||||
|
||||
public System.IO.Stream FileInputStream => (System.IO.Stream) new SubStream((System.IO.Stream) File.Open(this.FileName, FileMode.Open, FileAccess.Read, FileShare.Read), this.Offset, this.Length, true);
|
||||
|
||||
public string OriginalFileName { get; set; }
|
||||
|
||||
public System.IO.Stream FileOutputStream => (System.IO.Stream) new SubStream((System.IO.Stream) File.Open(this.FileName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Read), this.Offset, this.Length, true);
|
||||
|
||||
public string VirtualName => Path.ChangeExtension(string.Format("track{0:00}", (object) this.Index), DiscFileUtils.GetExtensionForDiscTrack((IDiscTrack) this));
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
this.Dispose(true);
|
||||
GC.SuppressFinalize((object) this);
|
||||
}
|
||||
|
||||
private void Dispose(bool disposing)
|
||||
{
|
||||
if (this.disposed)
|
||||
return;
|
||||
if (disposing)
|
||||
this.Close();
|
||||
this.disposed = true;
|
||||
}
|
||||
}
|
||||
}
|
149
SEGATools/DiscFileSystem/GenericImageConverter.cs
Normal file
149
SEGATools/DiscFileSystem/GenericImageConverter.cs
Normal file
|
@ -0,0 +1,149 @@
|
|||
// Decompiled with JetBrains decompiler
|
||||
// Type: SEGATools.DiscFileSystem.GenericImageConverter
|
||||
// Assembly: SEGATools, Version=1.0.3.0, Culture=neutral, PublicKeyToken=611be24fdeb07e08
|
||||
// MVID: D631183F-57B1-40A1-B502-5364D288307A
|
||||
// Assembly location: SEGATools.dll
|
||||
|
||||
using ImageReader.DiscSectors;
|
||||
using ImageReader.ImageReader;
|
||||
using ImageReader.Stream;
|
||||
using SEGATools.Security;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace SEGATools.DiscFileSystem
|
||||
{
|
||||
public class GenericImageConverter : IDiscFileSystemConverter
|
||||
{
|
||||
private static readonly Logger.ILog logger = Logger.CreateLog();
|
||||
private static readonly Regex FIND_NEXT_FILE = new Regex("^(?<prefix>.*)(?<index>[0-9]{2}?)$", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline);
|
||||
private static readonly int INVALID_FILE_INDEX = -1;
|
||||
private static readonly int DEFAULT_FILE_INDEX = 1;
|
||||
private IDiscSector discSector;
|
||||
|
||||
public GenericImageConverter(IDiscSector discSector) => this.discSector = discSector;
|
||||
|
||||
public IDiscFileSystem ToDiscFileSystem(string imageFileName)
|
||||
{
|
||||
InitialProgram initialProgram = this.GetInitialProgram(imageFileName, this.discSector);
|
||||
List<IDiscTrack> tracks = new List<IDiscTrack>();
|
||||
int index = this.GetIndexFromFileName(imageFileName);
|
||||
if (index == GenericImageConverter.INVALID_FILE_INDEX)
|
||||
index = GenericImageConverter.DEFAULT_FILE_INDEX;
|
||||
GenericImageConverter.TrackFile trackFile = new GenericImageConverter.TrackFile(index, imageFileName);
|
||||
uint num = 0;
|
||||
if (this.ContainsNonEmptyISO9660FileSystem(trackFile, num))
|
||||
{
|
||||
IDiscTrack discTrack = (IDiscTrack) new DiscTrack(trackFile.FileName, 0L, trackFile.Length, num, trackFile.Index, TrackModeType.Data, this.discSector);
|
||||
tracks.Add(discTrack);
|
||||
}
|
||||
else if (initialProgram != null && initialProgram.TableOfContent != null && this.ContainsNonEmptyISO9660FileSystem(trackFile, initialProgram.TableOfContent.FirstTrack.FrameAddress))
|
||||
{
|
||||
uint frameAddress = initialProgram.TableOfContent.FirstTrack.FrameAddress;
|
||||
IDiscTrack discTrack1 = (IDiscTrack) new DiscTrack(trackFile.FileName, 0L, trackFile.Length, frameAddress, trackFile.Index, TrackModeType.Data, this.discSector);
|
||||
tracks.Add(discTrack1);
|
||||
GenericImageConverter.TrackFile nextImageFile = this.FindNextImageFile(imageFileName);
|
||||
if (initialProgram.TableOfContent.HasSplitedDataTracks && nextImageFile != null)
|
||||
{
|
||||
IDiscTrack discTrack2 = (IDiscTrack) new DiscTrack(nextImageFile.FileName, 0L, nextImageFile.Length, initialProgram.TableOfContent.LastTrack.FrameAddress, nextImageFile.Index, TrackModeType.Data, this.discSector);
|
||||
tracks.Add(discTrack2);
|
||||
}
|
||||
}
|
||||
IDiscSession discSession = (IDiscSession) new DiscSession(1, string.Format(DiscSession.DEFAULT_SESSION_NAME_WITH_FORMAT, (object) 1), tracks);
|
||||
List<IDiscSession> sessions = new List<IDiscSession>();
|
||||
sessions.Add(discSession);
|
||||
bool supportCueSheet = tracks.Count == 1;
|
||||
return (IDiscFileSystem) new SEGATools.DiscFileSystem.DiscFileSystem(imageFileName, sessions, true, supportCueSheet);
|
||||
}
|
||||
|
||||
private bool ContainsNonEmptyISO9660FileSystem(
|
||||
GenericImageConverter.TrackFile trackFile,
|
||||
uint lba)
|
||||
{
|
||||
IDiscTrack discTrack = (IDiscTrack) new DiscTrack(trackFile.FileName, 0L, trackFile.Length, lba, trackFile.Index, TrackModeType.Data, this.discSector);
|
||||
using (DiscImageReader discImageReader = new DiscImageReader())
|
||||
{
|
||||
try
|
||||
{
|
||||
discImageReader.Open(discTrack.FileInputStream, discTrack.LogicalBlockAddress, this.discSector);
|
||||
return discImageReader.RootDirectoryRecord.UsedSpace > 0U;
|
||||
}
|
||||
catch (DiscImageReaderException ex)
|
||||
{
|
||||
logger.Error(ex);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private InitialProgram GetInitialProgram(string imageFileName, IDiscSector sector)
|
||||
{
|
||||
try
|
||||
{
|
||||
byte[] buffer;
|
||||
using (DiscSectorStream discSectorStream = new DiscSectorStream(imageFileName, sector, 0U, InitialProgram.IP_FILESIZE))
|
||||
{
|
||||
buffer = new byte[discSectorStream.Length];
|
||||
discSectorStream.Read(buffer, 0, buffer.Length);
|
||||
}
|
||||
return InitialProgramConverter.ToInitialProgram(buffer, 0);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
}
|
||||
return (InitialProgram) null;
|
||||
}
|
||||
|
||||
private GenericImageConverter.TrackFile FindNextImageFile(string fileName)
|
||||
{
|
||||
int startIndex = this.GetIndexFromFileName(fileName);
|
||||
if (startIndex == GenericImageConverter.INVALID_FILE_INDEX)
|
||||
return (GenericImageConverter.TrackFile) null;
|
||||
string prefixFromFileName = this.GetFileNamePrefixFromFileName(fileName);
|
||||
if (string.IsNullOrEmpty(prefixFromFileName))
|
||||
return (GenericImageConverter.TrackFile) null;
|
||||
string[] array = ((IEnumerable<string>) Directory.GetFiles(Path.GetDirectoryName(fileName), prefixFromFileName + "*" + Path.GetExtension(fileName))).Where<string>((Func<string, bool>) (FilePath => this.GetIndexFromFileName(FilePath) > startIndex)).ToArray<string>();
|
||||
if (array.Length <= 0)
|
||||
return (GenericImageConverter.TrackFile) null;
|
||||
string fileName1 = array[0];
|
||||
return new GenericImageConverter.TrackFile(this.GetIndexFromFileName(fileName1), fileName1);
|
||||
}
|
||||
|
||||
private string GetFileNamePrefixFromFileName(string fileName)
|
||||
{
|
||||
string withoutExtension = Path.GetFileNameWithoutExtension(fileName);
|
||||
Match match = GenericImageConverter.FIND_NEXT_FILE.Match(withoutExtension);
|
||||
return match.Success ? match.Groups["prefix"].Value : string.Empty;
|
||||
}
|
||||
|
||||
private int GetIndexFromFileName(string fileName)
|
||||
{
|
||||
string withoutExtension = Path.GetFileNameWithoutExtension(fileName);
|
||||
Match match = GenericImageConverter.FIND_NEXT_FILE.Match(withoutExtension);
|
||||
return match.Success ? int.Parse(match.Groups["index"].Value) : GenericImageConverter.INVALID_FILE_INDEX;
|
||||
}
|
||||
|
||||
private class TrackFile
|
||||
{
|
||||
public int Index { get; private set; }
|
||||
|
||||
public long Length { get; private set; }
|
||||
|
||||
public string FileName { get; private set; }
|
||||
|
||||
public TrackFile(int index, string fileName)
|
||||
{
|
||||
this.Index = index;
|
||||
this.FileName = fileName;
|
||||
this.Length = new FileInfo(fileName).Length;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
45
SEGATools/DiscFileSystem/IDiscFileSystem.cs
Normal file
45
SEGATools/DiscFileSystem/IDiscFileSystem.cs
Normal file
|
@ -0,0 +1,45 @@
|
|||
// Decompiled with JetBrains decompiler
|
||||
// Type: SEGATools.DiscFileSystem.IDiscFileSystem
|
||||
// Assembly: SEGATools, Version=1.0.3.0, Culture=neutral, PublicKeyToken=611be24fdeb07e08
|
||||
// MVID: D631183F-57B1-40A1-B502-5364D288307A
|
||||
// Assembly location: SEGATools.dll
|
||||
|
||||
using ImageReader.ISO9660.DirectoryRecords;
|
||||
using ImageReader.Stream;
|
||||
using SEGATools.Binary;
|
||||
using SEGATools.Encrypt;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace SEGATools.DiscFileSystem
|
||||
{
|
||||
public interface IDiscFileSystem
|
||||
{
|
||||
bool CanExtractData { get; }
|
||||
|
||||
bool CanBeExportedToCueSheet { get; }
|
||||
|
||||
bool CanBeExportedToGdi { get; }
|
||||
|
||||
List<IDiscSession> Sessions { get; }
|
||||
|
||||
string FileName { get; }
|
||||
|
||||
string DiscName { get; set; }
|
||||
|
||||
DirectoryRecord MainBinary { get; set; }
|
||||
|
||||
DiscImageType DiscType { get; set; }
|
||||
|
||||
List<IDiscTrack> AllTracks { get; }
|
||||
|
||||
DiscSectorStream GetDiscStreamForDirectoryRecord(DirectoryRecord directoryRecord);
|
||||
|
||||
void RegisterLibraries(object file, List<SEGALibrary> Libraries);
|
||||
|
||||
List<SEGALibrary> GetSEGALibraries(object file);
|
||||
|
||||
DESKey NaomiDESKey { get; set; }
|
||||
|
||||
void Close();
|
||||
}
|
||||
}
|
13
SEGATools/DiscFileSystem/IDiscFileSystemConverter.cs
Normal file
13
SEGATools/DiscFileSystem/IDiscFileSystemConverter.cs
Normal file
|
@ -0,0 +1,13 @@
|
|||
// Decompiled with JetBrains decompiler
|
||||
// Type: SEGATools.DiscFileSystem.IDiscFileSystemConverter
|
||||
// Assembly: SEGATools, Version=1.0.3.0, Culture=neutral, PublicKeyToken=611be24fdeb07e08
|
||||
// MVID: D631183F-57B1-40A1-B502-5364D288307A
|
||||
// Assembly location: SEGATools.dll
|
||||
|
||||
namespace SEGATools.DiscFileSystem
|
||||
{
|
||||
public interface IDiscFileSystemConverter
|
||||
{
|
||||
IDiscFileSystem ToDiscFileSystem(string imageFileName);
|
||||
}
|
||||
}
|
42
SEGATools/DiscFileSystem/IDiscSession.cs
Normal file
42
SEGATools/DiscFileSystem/IDiscSession.cs
Normal file
|
@ -0,0 +1,42 @@
|
|||
// Decompiled with JetBrains decompiler
|
||||
// Type: SEGATools.DiscFileSystem.IDiscSession
|
||||
// Assembly: SEGATools, Version=1.0.3.0, Culture=neutral, PublicKeyToken=611be24fdeb07e08
|
||||
// MVID: D631183F-57B1-40A1-B502-5364D288307A
|
||||
// Assembly location: SEGATools.dll
|
||||
|
||||
using ImageReader.ISO9660.DirectoryRecords;
|
||||
using ImageReader.ISO9660.VolumeDescriptors;
|
||||
using SEGATools.Security;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace SEGATools.DiscFileSystem
|
||||
{
|
||||
public interface IDiscSession
|
||||
{
|
||||
List<IDiscTrack> Tracks { get; }
|
||||
|
||||
List<IDiscTrack> DataTracks { get; }
|
||||
|
||||
IDiscTrack FirstDataTrack { get; }
|
||||
|
||||
IDiscTrack LastDataTrack { get; }
|
||||
|
||||
List<IDiscTrack> AudioTracks { get; }
|
||||
|
||||
int Index { get; }
|
||||
|
||||
string Name { get; }
|
||||
|
||||
DirectoryRecord MainBinary { get; set; }
|
||||
|
||||
InitialProgram BootStrap { get; set; }
|
||||
|
||||
PrimaryVolumeDescriptor PrimaryVolumeDescriptor { get; set; }
|
||||
|
||||
DirectoryRecord RootDirectoryRecord { get; set; }
|
||||
|
||||
IDiscFileSystem Disc { get; set; }
|
||||
|
||||
void Close();
|
||||
}
|
||||
}
|
35
SEGATools/DiscFileSystem/IDiscTrack.cs
Normal file
35
SEGATools/DiscFileSystem/IDiscTrack.cs
Normal file
|
@ -0,0 +1,35 @@
|
|||
// Decompiled with JetBrains decompiler
|
||||
// Type: SEGATools.DiscFileSystem.IDiscTrack
|
||||
// Assembly: SEGATools, Version=1.0.3.0, Culture=neutral, PublicKeyToken=611be24fdeb07e08
|
||||
// MVID: D631183F-57B1-40A1-B502-5364D288307A
|
||||
// Assembly location: SEGATools.dll
|
||||
|
||||
using ImageReader.DiscSectors;
|
||||
using SEGATools.VirtualFile;
|
||||
using System;
|
||||
|
||||
namespace SEGATools.DiscFileSystem
|
||||
{
|
||||
public interface IDiscTrack : IVirtualFile, IDisposable
|
||||
{
|
||||
string FileName { get; }
|
||||
|
||||
string Name { get; }
|
||||
|
||||
int Index { get; }
|
||||
|
||||
long Length { get; }
|
||||
|
||||
uint LogicalBlockAddress { get; }
|
||||
|
||||
long Offset { get; }
|
||||
|
||||
TrackModeType TrackData { get; }
|
||||
|
||||
IDiscSector TrackSector { get; }
|
||||
|
||||
IDiscSession Session { get; set; }
|
||||
|
||||
void Close();
|
||||
}
|
||||
}
|
14
SEGATools/DiscFileSystem/TrackModeType.cs
Normal file
14
SEGATools/DiscFileSystem/TrackModeType.cs
Normal file
|
@ -0,0 +1,14 @@
|
|||
// Decompiled with JetBrains decompiler
|
||||
// Type: SEGATools.DiscFileSystem.TrackModeType
|
||||
// Assembly: SEGATools, Version=1.0.3.0, Culture=neutral, PublicKeyToken=611be24fdeb07e08
|
||||
// MVID: D631183F-57B1-40A1-B502-5364D288307A
|
||||
// Assembly location: SEGATools.dll
|
||||
|
||||
namespace SEGATools.DiscFileSystem
|
||||
{
|
||||
public enum TrackModeType : short
|
||||
{
|
||||
Audio = 0,
|
||||
Data = 4,
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue