using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using IsoFilePatcher.Iso9660;
namespace IsoFilePatcher
{
internal static class Program
{
///
/// 应用程序的主入口点。
///
[STAThread]
private static void Main(string[] args)
{
try
{
MainInternal(args);
}
catch (Exception ex)
{
Console.WriteLine();
Console.WriteLine("----ERROR BEGIN----");
Console.WriteLine(ex);
Console.WriteLine("-----ERROR END-----");
}
Console.WriteLine();
Console.Write("Press ENTER to exit...");
Console.ReadLine();
}
private static void MainInternal(string[] args)
{
if (args.Length != 3)
{
Console.WriteLine($"Useage: {Path.GetFileName(Application.ExecutablePath)} ");
Console.WriteLine($"Example: {Path.GetFileName(Application.ExecutablePath)} C:\\PS3.ISO PS3_GAME\\USRDIR\\EBOOT.BIN C:\\RESIGNED_EBOOT.BIN");
return;
}
var isoFile = args[0];
var path = args[1];
var dataToReplaceFrom = args[2];
Console.WriteLine($"Opening {isoFile} ...");
using (var isoStream = new FileStream(isoFile, FileMode.Open, FileAccess.ReadWrite))
{
Console.WriteLine("Skipping system area...");
isoStream.Position = 16 * Constants.SectorSize;
Console.WriteLine("Parsing VolumeDescriptor...");
var descriptors = new List();
do
{
var item = VolumeDescriptor.Parse(isoStream);
if (item.IsVolumeDescriptorSetTerminator) break;
descriptors.Add(item);
} while (true);
Console.WriteLine("Parsing path entries...");
var root = (descriptors.FirstOrDefault(p => p.Type == 2) ?? descriptors[0]).RootPathEntry;
root.ScanChilds(isoStream);
Console.WriteLine("Locating file...");
var pathEntries = path.Split(Path.DirectorySeparatorChar);
var currentPath = root;
foreach (var item in pathEntries)
{
var target = currentPath.ChildPathEntries.FirstOrDefault(p => 0 == string.Compare(p.Name, item, StringComparison.OrdinalIgnoreCase));
if (target == null)
throw new ArgumentException("Path not found");
currentPath = target;
}
if (currentPath.IsDirectory)
throw new ArgumentException("Path is a directory");
Console.WriteLine("Feasibility checking...");
var dataFile = new FileInfo(dataToReplaceFrom);
if (false == dataFile.Exists)
throw new FileNotFoundException("File not found", dataToReplaceFrom);
if (dataFile.Length > currentPath.DataLength)
throw new ArgumentException("File large than orignal, can not continue");
Console.WriteLine("Operation in progress...");
isoStream.Position = currentPath.ExtentLba * currentPath.VolumeDescriptor.LogicalBlockSize;
using (var stream = dataFile.OpenRead())
{
stream.CopyTo(isoStream);
}
Console.WriteLine("Flushing file...");
isoStream.Flush();
Console.WriteLine("Closing file...");
isoStream.Close();
isoStream.Dispose();
Console.WriteLine("Operation completed successfully.");
}
}
}
}