initial commit
This commit is contained in:
commit
1b60743303
274 changed files with 25866 additions and 0 deletions
347
SEGATools/Disc/DiscExtractor.cs
Normal file
347
SEGATools/Disc/DiscExtractor.cs
Normal file
|
@ -0,0 +1,347 @@
|
|||
// Decompiled with JetBrains decompiler
|
||||
// Type: SEGATools.Disc.DiscExtractor
|
||||
// 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.DiscFileSystem;
|
||||
using SEGATools.Security;
|
||||
using SEGATools.UserProcess;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
|
||||
namespace SEGATools.Disc
|
||||
{
|
||||
public class DiscExtractor : UserProcessBase
|
||||
{
|
||||
private static readonly int OutputFileStreamBuffer = 524288;
|
||||
|
||||
public event AsyncOperationProgressChangedEventHandler ExtractionProgressChanged
|
||||
{
|
||||
add => this.AsyncOperationProgressChanged += value;
|
||||
remove => this.AsyncOperationProgressChanged -= value;
|
||||
}
|
||||
|
||||
public event AsyncOperationCompletedEventHandler ExtractionCompleted
|
||||
{
|
||||
add => this.AsyncOperationCompleted += value;
|
||||
remove => this.AsyncOperationCompleted -= value;
|
||||
}
|
||||
|
||||
public IDiscFileSystem DiscFileSystem { get; set; }
|
||||
|
||||
public DiscExtractor()
|
||||
{
|
||||
}
|
||||
|
||||
public DiscExtractor(IContainer container)
|
||||
: base(container)
|
||||
{
|
||||
}
|
||||
|
||||
public void ExtractPathsAsync(
|
||||
List<DirectoryRecord> directoryRecords,
|
||||
string outputPath,
|
||||
object taskId)
|
||||
{
|
||||
this.ExtractPathsAsync(directoryRecords, outputPath, (SendOrPostCallback) null, taskId);
|
||||
}
|
||||
|
||||
public void ExtractDirectoryRecordsAsync(
|
||||
DirectoryRecord directoryRecord,
|
||||
string outputPath,
|
||||
object taskId)
|
||||
{
|
||||
this.ExtractPathsAsync(directoryRecord, outputPath, (SendOrPostCallback) null, taskId);
|
||||
}
|
||||
|
||||
public void ExtractDiscTracksAsync(IDiscTrack track, string outputFileName, object taskId) => this.ExtractDiscTracksAsync(new List<IDiscTrack>()
|
||||
{
|
||||
track
|
||||
}, outputFileName, taskId);
|
||||
|
||||
public void ExtractBootStrap(InitialProgram ip, string outputFilename)
|
||||
{
|
||||
if (ip == null)
|
||||
throw new ArgumentNullException(nameof (ip));
|
||||
if (string.IsNullOrEmpty(outputFilename))
|
||||
throw new ArgumentNullException(nameof (outputFilename));
|
||||
using (System.IO.Stream stream = ip.Stream)
|
||||
{
|
||||
byte[] buffer = new byte[stream.Length];
|
||||
using (FileStream fileStream = new FileStream(outputFilename, FileMode.OpenOrCreate))
|
||||
{
|
||||
stream.Read(buffer, 0, buffer.Length);
|
||||
fileStream.Write(buffer, 0, buffer.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ExtractPathsAsync(
|
||||
DirectoryRecord directoryRecord,
|
||||
string outputPath,
|
||||
SendOrPostCallback callBack,
|
||||
object taskId)
|
||||
{
|
||||
this.ExtractPathsAsync(new List<DirectoryRecord>()
|
||||
{
|
||||
directoryRecord
|
||||
}, outputPath, callBack, taskId);
|
||||
}
|
||||
|
||||
private void ExtractPathsAsync(
|
||||
List<DirectoryRecord> directoryRecords,
|
||||
string outputPath,
|
||||
SendOrPostCallback callBack,
|
||||
object taskId)
|
||||
{
|
||||
AsyncOperation asyncOperation = this.CreateAsyncOperation(taskId);
|
||||
new DiscExtractor.FileExtractorWorkerEventHandler(this.FileExtractorWorker).BeginInvoke(directoryRecords, outputPath, asyncOperation, (AsyncCallback) null, (object) null);
|
||||
}
|
||||
|
||||
private void ExtractDiscTracksAsync(List<IDiscTrack> tracks, string outputPath, object taskId)
|
||||
{
|
||||
AsyncOperation asyncOperation = this.CreateAsyncOperation(taskId);
|
||||
new DiscExtractor.TrackExtractorWorkerEventHandler(this.TrackExtractorWorker).BeginInvoke(tracks, outputPath, asyncOperation, (AsyncCallback) null, (object) null);
|
||||
}
|
||||
|
||||
private void FileExtractorWorker(
|
||||
List<DirectoryRecord> directoryRecords,
|
||||
string outputPath,
|
||||
AsyncOperation asyncOp)
|
||||
{
|
||||
string lastFileName = string.Empty;
|
||||
string Filename = string.Empty;
|
||||
Exception exception = (Exception) null;
|
||||
long num1 = 0;
|
||||
List<DirectoryRecord> source = new List<DirectoryRecord>();
|
||||
foreach (DirectoryRecord directoryRecord in directoryRecords)
|
||||
{
|
||||
num1 += (long) directoryRecord.UsedSpace;
|
||||
source.Add(directoryRecord);
|
||||
source.AddRange((IEnumerable<DirectoryRecord>) directoryRecord.GetAllSubDirectories());
|
||||
}
|
||||
List<DirectoryRecord> list = source.Distinct<DirectoryRecord>().ToList<DirectoryRecord>();
|
||||
long num2 = num1;
|
||||
string commonPathPrefix = DirectoryRecord.FindCommonPathPrefix(directoryRecords);
|
||||
UserProcessBase.logger.DebugFormat("The longest path prefix for all {0} files is {1}", (object) list.Count, (object) commonPathPrefix);
|
||||
try
|
||||
{
|
||||
this.CheckForEnoughFreeDiscSpace(num1, outputPath);
|
||||
foreach (DirectoryRecord directoryRecord in list)
|
||||
{
|
||||
if (!this.TaskCanceled(asyncOp))
|
||||
{
|
||||
Filename = directoryRecord.FullPath;
|
||||
string str1;
|
||||
if (list.Count == 1 && !directoryRecord.IsDirectory)
|
||||
{
|
||||
str1 = outputPath;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!directoryRecord.FullPath.StartsWith(commonPathPrefix))
|
||||
throw new DiscExtractorException(string.Format("The path \"{0}\" was expected to have the prefix \"{1}\"", (object) directoryRecord.FullPath, (object) commonPathPrefix));
|
||||
string str2 = directoryRecord.FullPath.Remove(0, commonPathPrefix.Length);
|
||||
if (Path.IsPathRooted(str2))
|
||||
str2 = str2.Substring(1);
|
||||
str1 = Path.Combine(outputPath, str2);
|
||||
}
|
||||
UserProcessBase.logger.DebugFormat("Extract {0} to {1}", (object) Filename, (object) str1);
|
||||
if (directoryRecord.IsDirectory)
|
||||
{
|
||||
UserProcessBase.logger.DebugFormat("Create output directory {0}", (object) str1);
|
||||
DirectoryInfo directoryInfo = new DirectoryInfo(str1);
|
||||
if (!directoryInfo.Exists)
|
||||
{
|
||||
Directory.CreateDirectory(directoryInfo.FullName);
|
||||
DateTime dateTime = directoryRecord.RecordingDateTime.HasValue ? directoryRecord.RecordingDateTime.Value : DateTime.Now;
|
||||
directoryInfo.CreationTime = dateTime;
|
||||
directoryInfo.LastWriteTime = dateTime;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lastFileName = str1;
|
||||
num2 = this.ExtractDirectoryRecord(directoryRecord, str1, num1, num2, asyncOp);
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
exception = ex;
|
||||
UserProcessBase.logger.ErrorFormat("Unable to extract the data: {0}", (object) exception);
|
||||
}
|
||||
this.DoExtractionCleanupIfNeeded(lastFileName, num2, exception, asyncOp);
|
||||
this.ReportCompletion(Filename, exception, asyncOp);
|
||||
}
|
||||
|
||||
private long ExtractDirectoryRecord(
|
||||
DirectoryRecord directoryRecord,
|
||||
string FileOutputPath,
|
||||
long totalNumberOfBytesToExtract,
|
||||
long totalNumberOfBytesRemaining,
|
||||
AsyncOperation asyncOp)
|
||||
{
|
||||
using (DiscSectorStream forDirectoryRecord = this.DiscFileSystem.GetDiscStreamForDirectoryRecord(directoryRecord))
|
||||
{
|
||||
using (FileStream fileStream = new FileStream(FileOutputPath, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None, DiscExtractor.OutputFileStreamBuffer))
|
||||
{
|
||||
long length = forDirectoryRecord.Length;
|
||||
byte[] buffer = new byte[DiscExtractor.OutputFileStreamBuffer];
|
||||
while (length > 0L)
|
||||
{
|
||||
if (!this.TaskCanceled(asyncOp))
|
||||
{
|
||||
int count = forDirectoryRecord.Read(buffer, 0, buffer.Length);
|
||||
length -= (long) count;
|
||||
totalNumberOfBytesRemaining -= (long) count;
|
||||
fileStream.Write(buffer, 0, count);
|
||||
this.ReportProgress(this.CreateProgressChangedEventArgs(directoryRecord.FullPath, FileOutputPath, forDirectoryRecord.Length, length, totalNumberOfBytesToExtract, totalNumberOfBytesRemaining, asyncOp), asyncOp);
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
DateTime dateTime = directoryRecord.RecordingDateTime.HasValue ? directoryRecord.RecordingDateTime.Value : DateTime.Now;
|
||||
File.SetCreationTime(FileOutputPath, dateTime);
|
||||
File.SetLastWriteTime(FileOutputPath, dateTime);
|
||||
return totalNumberOfBytesRemaining;
|
||||
}
|
||||
|
||||
private void TrackExtractorWorker(
|
||||
List<IDiscTrack> tracks,
|
||||
string outputPath,
|
||||
AsyncOperation asyncOp)
|
||||
{
|
||||
Exception exception = (Exception) null;
|
||||
string lastFileName = string.Empty;
|
||||
long ofBytesToExtract = this.ComputeNumberOfBytesToExtract(tracks);
|
||||
this.CheckForEnoughFreeDiscSpace(ofBytesToExtract, outputPath);
|
||||
long num = ofBytesToExtract;
|
||||
try
|
||||
{
|
||||
foreach (IDiscTrack track in tracks)
|
||||
{
|
||||
if (!this.TaskCanceled(asyncOp))
|
||||
{
|
||||
string outputFileName = tracks.Count > 1 ? Path.Combine(outputPath, Path.GetFileName(track.VirtualName)) : outputPath;
|
||||
lastFileName = outputFileName;
|
||||
num = this.ExtractDiscTrack(track, outputFileName, ofBytesToExtract, num, asyncOp);
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
exception = ex;
|
||||
UserProcessBase.logger.ErrorFormat("Unable to extract the track: {0}", (object) exception);
|
||||
}
|
||||
this.DoExtractionCleanupIfNeeded(lastFileName, num, exception, asyncOp);
|
||||
this.ReportCompletion(outputPath, exception, asyncOp);
|
||||
}
|
||||
|
||||
private long ExtractDiscTrack(
|
||||
IDiscTrack track,
|
||||
string outputFileName,
|
||||
long totalNumberOfBytesToExtract,
|
||||
long totalNumberOfBytesRemaining,
|
||||
AsyncOperation asyncOp)
|
||||
{
|
||||
using (System.IO.Stream fileInputStream = track.FileInputStream)
|
||||
{
|
||||
using (FileStream fileStream = new FileStream(outputFileName, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None, DiscExtractor.OutputFileStreamBuffer))
|
||||
{
|
||||
long length = fileInputStream.Length;
|
||||
byte[] buffer = new byte[DiscExtractor.OutputFileStreamBuffer];
|
||||
while (length > 0L)
|
||||
{
|
||||
if (!this.TaskCanceled(asyncOp))
|
||||
{
|
||||
int count = fileInputStream.Read(buffer, 0, buffer.Length);
|
||||
length -= (long) count;
|
||||
totalNumberOfBytesRemaining -= (long) count;
|
||||
fileStream.Write(buffer, 0, count);
|
||||
this.ReportProgress(this.CreateProgressChangedEventArgs(track.FileName, outputFileName, fileInputStream.Length, length, totalNumberOfBytesToExtract, totalNumberOfBytesRemaining, asyncOp), asyncOp);
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return totalNumberOfBytesRemaining;
|
||||
}
|
||||
|
||||
private long ComputeNumberOfBytesToExtract(List<IDiscTrack> tracks)
|
||||
{
|
||||
long num = 0;
|
||||
foreach (IDiscTrack track in tracks)
|
||||
num += track.FileInputStream.Length;
|
||||
return num;
|
||||
}
|
||||
|
||||
private void CheckForEnoughFreeDiscSpace(long requiredSpaceInBytes, string outputPath)
|
||||
{
|
||||
if (requiredSpaceInBytes > new DriveInfo(outputPath.Substring(0, 3)).AvailableFreeSpace)
|
||||
{
|
||||
UserProcessBase.logger.ErrorFormat("Extraction requires {0} bytes of free disc space in drive {1}", (object) requiredSpaceInBytes, (object) outputPath.Substring(0, 3));
|
||||
throw new IOException("Not enough free disc space!");
|
||||
}
|
||||
}
|
||||
|
||||
private UserProcessProgressChangedEventArgs CreateProgressChangedEventArgs(
|
||||
string input,
|
||||
string output,
|
||||
long numberOfBytesToExtract,
|
||||
long remainingBytesToExtract,
|
||||
long totalNumberOfBytesToExtract,
|
||||
long totalNumberOfBytesRemaining,
|
||||
AsyncOperation asyncOp)
|
||||
{
|
||||
int progressPercentage = (int) ((double) (numberOfBytesToExtract - remainingBytesToExtract) / (double) numberOfBytesToExtract * 100.0);
|
||||
int totalProgressPercentage = (int) ((double) (totalNumberOfBytesToExtract - totalNumberOfBytesRemaining) / (double) totalNumberOfBytesToExtract * 100.0);
|
||||
return new UserProcessProgressChangedEventArgs(input, output, progressPercentage, totalProgressPercentage, asyncOp.UserSuppliedState);
|
||||
}
|
||||
|
||||
private void DoExtractionCleanupIfNeeded(
|
||||
string lastFileName,
|
||||
long remainingBytes,
|
||||
Exception exception,
|
||||
AsyncOperation asyncOp)
|
||||
{
|
||||
if (!this.TaskCanceled(asyncOp) && exception == null || remainingBytes <= 0L)
|
||||
return;
|
||||
if (!File.Exists(lastFileName))
|
||||
return;
|
||||
try
|
||||
{
|
||||
File.Delete(lastFileName);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
UserProcessBase.logger.ErrorFormat("Unable to delete the file {0}: {1}", (object) lastFileName, (object) ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private delegate void FileExtractorWorkerEventHandler(
|
||||
List<DirectoryRecord> directoryRecords,
|
||||
string outputPath,
|
||||
AsyncOperation asyncOp);
|
||||
|
||||
private delegate void TrackExtractorWorkerEventHandler(
|
||||
List<IDiscTrack> tracks,
|
||||
string outputPath,
|
||||
AsyncOperation asyncOp);
|
||||
}
|
||||
}
|
23
SEGATools/Disc/DiscExtractorException.cs
Normal file
23
SEGATools/Disc/DiscExtractorException.cs
Normal file
|
@ -0,0 +1,23 @@
|
|||
// Decompiled with JetBrains decompiler
|
||||
// Type: SEGATools.Disc.DiscExtractorException
|
||||
// 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.Disc
|
||||
{
|
||||
public class DiscExtractorException : Exception
|
||||
{
|
||||
public DiscExtractorException(string message)
|
||||
: base(string.Format("Disc Extractor Error: {0}", (object) message))
|
||||
{
|
||||
}
|
||||
|
||||
public DiscExtractorException(string message, Exception innerException)
|
||||
: base(string.Format("Disc Extractor Error: {0}", (object) message), innerException)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
155
SEGATools/Disc/DiscFormatProvider.cs
Normal file
155
SEGATools/Disc/DiscFormatProvider.cs
Normal file
|
@ -0,0 +1,155 @@
|
|||
// Decompiled with JetBrains decompiler
|
||||
// Type: SEGATools.Disc.DiscFormatProvider
|
||||
// Assembly: SEGATools, Version=1.0.3.0, Culture=neutral, PublicKeyToken=611be24fdeb07e08
|
||||
// MVID: D631183F-57B1-40A1-B502-5364D288307A
|
||||
// Assembly location: SEGATools.dll
|
||||
|
||||
using SEGATools.FileFormat;
|
||||
using SEGATools.Properties;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace SEGATools.Disc
|
||||
{
|
||||
public class DiscFormatProvider : Component
|
||||
{
|
||||
private static readonly Logger.ILog logger = Logger.CreateLog();
|
||||
private static readonly string FILEFORMAT_NAMESPACE = "GDRomExplorer.ImageFileFormat";
|
||||
private static readonly string FILEFORMAT_PLUGIN_FOLDER = "Formats";
|
||||
private static List<IImageFileFormat> fileFormats;
|
||||
private IContainer components;
|
||||
|
||||
public List<IImageFileFormat> SupportedFileFormat => DiscFormatProvider.fileFormats.ToList<IImageFileFormat>();
|
||||
|
||||
public DiscFormatProvider()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
if (DiscFormatProvider.fileFormats != null)
|
||||
return;
|
||||
DiscFormatProvider.LoadImageFileFormatAssemblies();
|
||||
}
|
||||
|
||||
public DiscFormatProvider(IContainer container)
|
||||
{
|
||||
container.Add((IComponent) this);
|
||||
this.InitializeComponent();
|
||||
if (DiscFormatProvider.fileFormats != null)
|
||||
return;
|
||||
DiscFormatProvider.LoadImageFileFormatAssemblies();
|
||||
}
|
||||
|
||||
public string GetFileDialogFilters(params string[] fileExtensionFilters)
|
||||
{
|
||||
int num = 0;
|
||||
List<string> stringList1 = new List<string>();
|
||||
List<string> stringList2 = new List<string>();
|
||||
foreach (IImageFileFormat fileFormat in DiscFormatProvider.fileFormats)
|
||||
{
|
||||
string[] strArray = fileFormat.FileExtentions;
|
||||
if (fileExtensionFilters != null && fileExtensionFilters.Length > 0)
|
||||
strArray = ((IEnumerable<string>) fileFormat.FileExtentions).Where<string>((Func<string, bool>) (extension => ((IEnumerable<string>) fileExtensionFilters).Contains<string>(extension))).ToArray<string>();
|
||||
for (int index = 0; index < strArray.Length; ++index)
|
||||
{
|
||||
stringList1.Add(fileFormat.FileExtentionDescriptions[index]);
|
||||
string str = string.Format("*{0}", (object) fileFormat.FileExtentions[index]);
|
||||
stringList1.Add(str);
|
||||
stringList2.Add(str);
|
||||
++num;
|
||||
}
|
||||
}
|
||||
if (num > 1)
|
||||
{
|
||||
stringList1.Insert(0, string.Join(";", stringList2.ToArray()));
|
||||
stringList1.Insert(0, Resources.DiscFormatProviderAllExtensions);
|
||||
}
|
||||
return string.Join("|", stringList1.ToArray());
|
||||
}
|
||||
|
||||
public int GetFileFormatIndex(IImageFileFormat imageFileFormat) => DiscFormatProvider.fileFormats.IndexOf(imageFileFormat) + 2;
|
||||
|
||||
public bool IsFileExtensionSupported(string fileExtension) => this.FindImageFileFormatForFileExtension(fileExtension) != null;
|
||||
|
||||
public IImageFileFormat FindImageFileFormatForFileExtension(string fileExtension) => string.IsNullOrEmpty(fileExtension) ? (IImageFileFormat) null : DiscFormatProvider.fileFormats.Find((Predicate<IImageFileFormat>) (imageFileFormat => new List<string>((IEnumerable<string>) imageFileFormat.FileExtentions).Contains<string>(fileExtension, (IEqualityComparer<string>) StringComparer.InvariantCultureIgnoreCase)));
|
||||
|
||||
public string GetDescriptionForFileExtension(string extension, IImageFileFormat imageFileFormat)
|
||||
{
|
||||
for (int index = 0; index < imageFileFormat.FileExtentions.Length; ++index)
|
||||
{
|
||||
if (imageFileFormat.FileExtentions[index].Equals(extension, StringComparison.InvariantCultureIgnoreCase))
|
||||
return imageFileFormat.FileExtentionDescriptions[index];
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
private static void LoadImageFileFormatAssemblies()
|
||||
{
|
||||
string path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), DiscFormatProvider.FILEFORMAT_PLUGIN_FOLDER);
|
||||
try
|
||||
{
|
||||
DiscFormatProvider.LoadImageFileFormatAssembliesFromPluginPath(path);
|
||||
}
|
||||
catch (DirectoryNotFoundException ex)
|
||||
{
|
||||
DiscFormatProvider.logger.ErrorFormat("Unable to find the plugin folder: {0}", (object) path);
|
||||
logger.Error(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static void LoadImageFileFormatAssembliesFromPluginPath(string path)
|
||||
{
|
||||
DiscFormatProvider.fileFormats = new List<IImageFileFormat>();
|
||||
List<Type> typeList = new List<Type>();
|
||||
Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
||||
foreach (string file in Directory.GetFiles(path, "*.dll"))
|
||||
{
|
||||
try
|
||||
{
|
||||
List<Type> list = ((IEnumerable<Type>) Assembly.LoadFile(file).GetTypes()).Where<Type>((Func<Type, bool>) (t => t.IsClass && t.Namespace != null && t.Namespace.StartsWith("GDRomExplorer.ImageFileFormat") && typeof (IImageFileFormat).IsAssignableFrom(t))).ToList<Type>();
|
||||
typeList.AddRange((IEnumerable<Type>) list);
|
||||
}
|
||||
catch (ReflectionTypeLoadException ex)
|
||||
{
|
||||
DiscFormatProvider.logger.ErrorFormat("Unable to load types in namespace \"{0}\"", (object) DiscFormatProvider.FILEFORMAT_NAMESPACE);
|
||||
logger.Error(ex);
|
||||
return;
|
||||
}
|
||||
}
|
||||
DiscFormatProvider.logger.InfoFormat("Found {0} file formats to load", (object) typeList.Count);
|
||||
foreach (Type type in typeList)
|
||||
{
|
||||
try
|
||||
{
|
||||
IImageFileFormat instance = (IImageFileFormat) Activator.CreateInstance(type);
|
||||
if (DiscFormatProvider.fileFormats.Contains(instance))
|
||||
{
|
||||
DiscFormatProvider.logger.WarnFormat("File format {0} already loaded", (object) type.Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
instance.PluginAssemblyFileName = type.Assembly.CodeBase;
|
||||
DiscFormatProvider.fileFormats.Add(instance);
|
||||
DiscFormatProvider.logger.InfoFormat("File format {0} loaded", (object) type.Name);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
DiscFormatProvider.logger.ErrorFormat("Unable to load file format {0}: {1}", (object) type.Name, (object) ex);
|
||||
}
|
||||
}
|
||||
DiscFormatProvider.fileFormats = DiscFormatProvider.fileFormats.Distinct<IImageFileFormat>().ToList<IImageFileFormat>();
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && this.components != null)
|
||||
this.components.Dispose();
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
private void InitializeComponent() => this.components = (IContainer) new Container();
|
||||
}
|
||||
}
|
119
SEGATools/Disc/DiscOpener.cs
Normal file
119
SEGATools/Disc/DiscOpener.cs
Normal file
|
@ -0,0 +1,119 @@
|
|||
// Decompiled with JetBrains decompiler
|
||||
// Type: SEGATools.Disc.DiscOpener
|
||||
// Assembly: SEGATools, Version=1.0.3.0, Culture=neutral, PublicKeyToken=611be24fdeb07e08
|
||||
// MVID: D631183F-57B1-40A1-B502-5364D288307A
|
||||
// Assembly location: SEGATools.dll
|
||||
|
||||
using SEGATools.Binary;
|
||||
using SEGATools.DiscFileSystem;
|
||||
using SEGATools.Scanner;
|
||||
using SEGATools.UserProcess;
|
||||
using SEGATools.VirtualFile;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
|
||||
namespace SEGATools.Disc
|
||||
{
|
||||
public class DiscOpener : UserProcessBase
|
||||
{
|
||||
private IDiscFileSystem disc;
|
||||
private bool computePathTable;
|
||||
|
||||
public event AsyncOperationProgressChangedEventHandler FileOpenerProgressChanged
|
||||
{
|
||||
add => this.AsyncOperationProgressChanged += value;
|
||||
remove => this.AsyncOperationProgressChanged -= value;
|
||||
}
|
||||
|
||||
public event AsyncOperationCompletedEventHandler FileOpenerCompleted
|
||||
{
|
||||
add => this.AsyncOperationCompleted += value;
|
||||
remove => this.AsyncOperationCompleted -= value;
|
||||
}
|
||||
|
||||
public IDiscFileSystem DiscFileSystem => this.disc;
|
||||
|
||||
public DiscOpener()
|
||||
{
|
||||
}
|
||||
|
||||
public DiscOpener(IContainer container)
|
||||
: base(container)
|
||||
{
|
||||
}
|
||||
|
||||
public void OpenImageAsync(
|
||||
string Filename,
|
||||
IDiscFileSystemConverter ImageFileConverter,
|
||||
bool ComputePathTable)
|
||||
{
|
||||
AsyncOperation asyncOperation = this.CreateAsyncOperation((object) Guid.NewGuid());
|
||||
this.computePathTable = ComputePathTable;
|
||||
new DiscOpener.FileOpenerWorkerEventHandler(this.FileOpenerWorker).BeginInvoke(Filename, ImageFileConverter, asyncOperation, (AsyncCallback) null, (object) null);
|
||||
}
|
||||
|
||||
public void OpenImage(
|
||||
string Filename,
|
||||
IDiscFileSystemConverter ImageFileConverter,
|
||||
bool ComputePathTable)
|
||||
{
|
||||
this.computePathTable = ComputePathTable;
|
||||
this.FileOpenerWorker(Filename, ImageFileConverter, (AsyncOperation) null);
|
||||
}
|
||||
|
||||
public void CloseImage()
|
||||
{
|
||||
if (this.disc == null)
|
||||
return;
|
||||
this.disc.Close();
|
||||
this.disc = (IDiscFileSystem) null;
|
||||
}
|
||||
|
||||
private void FileOpenerWorker(
|
||||
string Filename,
|
||||
IDiscFileSystemConverter ImageFileConverter,
|
||||
AsyncOperation asyncOp)
|
||||
{
|
||||
Exception exception = (Exception) null;
|
||||
if (asyncOp != null)
|
||||
this.ReportProgress(new UserProcessProgressChangedEventArgs(Filename, 0, asyncOp.UserSuppliedState), asyncOp);
|
||||
if (this.disc != null)
|
||||
{
|
||||
this.disc.Close();
|
||||
this.disc = (IDiscFileSystem) null;
|
||||
}
|
||||
try
|
||||
{
|
||||
this.disc = DiscFileSystemBuilder.ToDisc(Filename, ImageFileConverter, this.computePathTable);
|
||||
foreach (IDiscSession discSession in this.disc.Sessions.FindAll((Predicate<IDiscSession>) (session => session.BootStrap != null)))
|
||||
{
|
||||
using (FileScanner fileScanner = new FileScanner())
|
||||
{
|
||||
IVirtualFile<System.IO.Stream> virtualFile = VirtualFileFactory.createVirtualFile(discSession.BootStrap.Stream, this.disc.FileName);
|
||||
List<SEGALibrary> Libraries = fileScanner.ScanFile<SEGALibrary>((IVirtualFile) virtualFile, FileScannerPattern.aPatternForSEGALibraries(), (IFileScannerResultConverter<SEGALibrary>) new FileScannerResultConverterForSEGALibrary());
|
||||
this.disc.RegisterLibraries((object) discSession.BootStrap, Libraries);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
exception = ex;
|
||||
this.disc = (IDiscFileSystem) null;
|
||||
UserProcessBase.logger.DebugFormat("Error while reading the image file: {0}", (object) ex);
|
||||
}
|
||||
if ((this.TaskCanceled(asyncOp) || exception != null) && this.disc != null)
|
||||
{
|
||||
this.disc.Close();
|
||||
this.disc = (IDiscFileSystem) null;
|
||||
}
|
||||
this.ReportCompletion(Filename, exception, asyncOp);
|
||||
}
|
||||
|
||||
private delegate void FileOpenerWorkerEventHandler(
|
||||
string filename,
|
||||
IDiscFileSystemConverter imageFileConverter,
|
||||
AsyncOperation asyncOp);
|
||||
}
|
||||
}
|
60
SEGATools/Disc/DiscSectorEncoder.cs
Normal file
60
SEGATools/Disc/DiscSectorEncoder.cs
Normal file
|
@ -0,0 +1,60 @@
|
|||
// Decompiled with JetBrains decompiler
|
||||
// Type: SEGATools.Disc.DiscSectorEncoder
|
||||
// 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.HashAlgorithm;
|
||||
using SEGATools.UserProcess;
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
|
||||
namespace SEGATools.Disc
|
||||
{
|
||||
public class DiscSectorEncoder : UserProcessBase
|
||||
{
|
||||
private EDC edcEncoder = new EDC();
|
||||
private ECC.ECCParityVectorAlgorithm eccPParityEncoder = (ECC.ECCParityVectorAlgorithm) new ECC.PParity();
|
||||
private ECC.ECCParityVectorAlgorithm eccQParityEncoder = (ECC.ECCParityVectorAlgorithm) new ECC.QParity();
|
||||
|
||||
public DiscSectorEncoder()
|
||||
{
|
||||
}
|
||||
|
||||
public DiscSectorEncoder(IContainer container)
|
||||
: base(container)
|
||||
{
|
||||
}
|
||||
|
||||
public void EncodeMode1Sectors(System.IO.Stream stream, int[] sectors)
|
||||
{
|
||||
byte[] numArray = new byte[DiscSectorCommon.RawSectorSize];
|
||||
for (int index = 0; index < sectors.Length; ++index)
|
||||
{
|
||||
UserProcessBase.logger.DebugFormat("Patching EDC and ECC data of sector {0}", (object) sectors[index]);
|
||||
stream.Seek((long) (sectors[index] * DiscSectorCommon.RawSectorSize), SeekOrigin.Begin);
|
||||
stream.Read(numArray, 0, DiscSectorCommon.RawSectorSize);
|
||||
this.ClearErrorDetectionAndCorrectionData(numArray);
|
||||
this.GenerateEDC(numArray);
|
||||
this.eccPParityEncoder.ComputeVectors(numArray);
|
||||
this.eccQParityEncoder.ComputeVectors(numArray);
|
||||
stream.Seek((long) -DiscSectorCommon.RawSectorSize, SeekOrigin.Current);
|
||||
stream.Write(numArray, 0, numArray.Length);
|
||||
}
|
||||
}
|
||||
|
||||
public void GenerateEDC(byte[] sector)
|
||||
{
|
||||
byte[] hash = this.edcEncoder.ComputeHash(sector, 0, EDC.SECTOR_DATA_LENGTH_FOR_EDC_COMPUTATION);
|
||||
Buffer.BlockCopy((Array) hash, 0, (Array) sector, EDC.EDC_DATA_OFFSET, hash.Length);
|
||||
}
|
||||
|
||||
public void ClearErrorDetectionAndCorrectionData(byte[] sector)
|
||||
{
|
||||
for (int edcDataOffset = EDC.EDC_DATA_OFFSET; edcDataOffset < sector.Length; ++edcDataOffset)
|
||||
sector[edcDataOffset] = (byte) 0;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue