GDROMExplorer/SEGATools/Security/InitialProgramConverter.cs
2021-07-26 13:04:16 -07:00

114 lines
6.2 KiB
C#

// Decompiled with JetBrains decompiler
// Type: SEGATools.Security.InitialProgramConverter
// Assembly: SEGATools, Version=1.0.3.0, Culture=neutral, PublicKeyToken=611be24fdeb07e08
// MVID: D631183F-57B1-40A1-B502-5364D288307A
// Assembly location: SEGATools.dll
using SEGATools.Graphics;
using System;
using System.Globalization;
using System.Text;
namespace SEGATools.Security
{
public class InitialProgramConverter
{
public static readonly int INITIAL_PROGRAM_SIZE = 32768;
private static readonly Logger.ILog logger = Logger.CreateLog();
private static readonly string HARDWARE_ID = "SEGA SEGAKATANA";
private static readonly string MAKER_ID = "SEGA ENTERPRISES";
private static readonly int OFFSET_HARDWARE_ID = 0;
private static readonly int OFFSET_MAKER_ID = 16;
private static readonly int OFFSET_CRC = 32;
private static readonly int OFFSET_DEVICE_INFORMATION = 37;
private static readonly int OFFSET_AREA_SYMBOLS = 48;
private static readonly int OFFSET_PERIPHERALS = 56;
private static readonly int OFFSET_PRODUCT_ID = 64;
private static readonly int OFFSET_PRODUCT_VERSION = 74;
private static readonly int OFFSET_RELEASE_DATE = 80;
private static readonly int OFFSET_MAIN_BINARY = 96;
private static readonly int OFFSET_COMPAGNY_NAME = 112;
private static readonly int OFFSET_SOFWARE_NAME = 128;
private static readonly int OFFSET_TOC = 256;
private static readonly int OFFSET_SEGA_LICENSE_LOGO = 9111;
private static readonly int OFFSET_SEGA_TRADEMARK_LOGO = 8812;
private static readonly int OFFSET_SEGA_CUSTOM_BRANDING_LOGO = 14368;
public static InitialProgram ToInitialProgram(byte[] buffer, int startIndex)
{
if (startIndex < 0 || buffer.Length - startIndex < InitialProgramConverter.INITIAL_PROGRAM_SIZE)
throw new ArgumentOutOfRangeException();
InitialProgram initialProgram = new InitialProgram();
initialProgram.HardwareID = InitialProgramConverter.ParseField("hardware ID", buffer, startIndex + InitialProgramConverter.OFFSET_HARDWARE_ID, 15);
if (!initialProgram.HardwareID.Equals(InitialProgramConverter.HARDWARE_ID))
throw new InitialProgramInvalidHardwareIdException();
initialProgram.MakerID = InitialProgramConverter.ParseField("maker ID", buffer, startIndex + InitialProgramConverter.OFFSET_MAKER_ID, 16);
if (!initialProgram.MakerID.Equals(InitialProgramConverter.MAKER_ID))
throw new InitialProgramInvalidMakerIdException();
initialProgram.DeviceInformation = InitialProgramConverter.ParseField("device information", buffer, startIndex + InitialProgramConverter.OFFSET_DEVICE_INFORMATION, 11);
initialProgram.AreaSymbols = InitialProgramConverter.ParseField("area symbols", buffer, startIndex + InitialProgramConverter.OFFSET_AREA_SYMBOLS, 7);
initialProgram.RawPeripherals = InitialProgramConverter.ParseField("area symbols", buffer, startIndex + InitialProgramConverter.OFFSET_PERIPHERALS, 7);
initialProgram.ProductID = InitialProgramConverter.ParseField("product ID", buffer, startIndex + InitialProgramConverter.OFFSET_PRODUCT_ID, 10);
initialProgram.ProductVersion = InitialProgramConverter.ParseField("product version", buffer, startIndex + InitialProgramConverter.OFFSET_PRODUCT_VERSION, 6);
initialProgram.CRC = InitialProgramConverter.ParseField("CRC", buffer, startIndex + InitialProgramConverter.OFFSET_CRC, 4);
initialProgram.ComputedCRC = InitialProgramUtils.ComputeCRC(initialProgram.ProductID, initialProgram.ProductVersion).ToString("X4");
string field = InitialProgramConverter.ParseField("release date", buffer, startIndex + InitialProgramConverter.OFFSET_RELEASE_DATE, 8);
try
{
initialProgram.ReleaseDate = DateTime.ParseExact(field, "yyyyMMdd", (IFormatProvider) CultureInfo.InvariantCulture, DateTimeStyles.None);
}
catch (Exception ex)
{
throw new InitialProgramReleaseDateParsingException(field, ex);
}
initialProgram.MainBinary = InitialProgramConverter.ParseField("main binary", buffer, startIndex + InitialProgramConverter.OFFSET_MAIN_BINARY, 16);
initialProgram.CompanyName = InitialProgramConverter.ParseField("company name", buffer, startIndex + InitialProgramConverter.OFFSET_COMPAGNY_NAME, 16);
initialProgram.SoftwareName = InitialProgramConverter.ParseField("software name", buffer, startIndex + InitialProgramConverter.OFFSET_SOFWARE_NAME, 128);
try
{
initialProgram.TableOfContent = InitialProgramTocConverter.ToInitialProgramToc(buffer, startIndex + InitialProgramConverter.OFFSET_TOC);
}
catch (InitialProgramTocException ex)
{
logger.Error(ex);
}
byte[] numArray = new byte[InitialProgramConverter.INITIAL_PROGRAM_SIZE];
Buffer.BlockCopy((Array) buffer, startIndex, (Array) numArray, 0, InitialProgramConverter.INITIAL_PROGRAM_SIZE);
initialProgram.RawData = numArray;
initialProgram.SegaLicenseImage = InitialProgramConverter.GetMRImage(buffer, startIndex + InitialProgramConverter.OFFSET_SEGA_LICENSE_LOGO);
initialProgram.SegaTradeMarkImage = InitialProgramConverter.GetMRImage(buffer, startIndex + InitialProgramConverter.OFFSET_SEGA_TRADEMARK_LOGO);
initialProgram.CustomBrandingImage = InitialProgramConverter.GetMRImage(buffer, startIndex + InitialProgramConverter.OFFSET_SEGA_CUSTOM_BRANDING_LOGO);
return initialProgram;
}
private static string ParseField(string fieldName, byte[] buffer, int startIndex, int lenght)
{
try
{
return Encoding.Default.GetString(buffer, startIndex, lenght);
}
catch (Exception ex)
{
throw new InitialProgramFieldParsingException(fieldName, startIndex, ex);
}
}
private static MRImage GetMRImage(byte[] buffer, int startIndex)
{
try
{
return MRImageConverter.ToMRImage(buffer, startIndex);
}
catch (MRImageIdentifierMissingException ex)
{
logger.Error(ex);
return (MRImage) null;
}
catch (MRImageDecompressionException ex)
{
InitialProgramConverter.logger.ErrorFormat("Unable to decompress MR image: {0}", (object) ex);
throw new InitialProgramInvalidMRImageException(startIndex, (Exception) ex);
}
}
}
}