// 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); } } } }