/* This file is part of CustomizeMii * Copyright (C) 2009 Leathl * * CustomizeMii is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * CustomizeMii is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ using System; using System.IO; using System.Reflection; namespace ForwardMii { public class SDSDHC_Forwarder { private string thisAppFolder; private bool toElf = false; public string AppFolder { get { return thisAppFolder; } set { thisAppFolder = value; } } public bool ForwardToElf { get { return toElf; } set { toElf = value; } } public SDSDHC_Forwarder() { } public SDSDHC_Forwarder(string AppFolder) { if (AppFolder.Length > 18 || AppFolder.Length < 3) throw new Exception("Application folder must be 3 - 18 chars!"); thisAppFolder = AppFolder; } public SDSDHC_Forwarder(string AppFolder, bool ForwardToElf) { if (AppFolder.Length > 18 || AppFolder.Length < 3) throw new Exception("Application folder must be 3 - 18 chars!"); thisAppFolder = AppFolder; toElf = ForwardToElf; } public void Clear() { thisAppFolder = string.Empty; toElf = false; } public void Save(string Destionation) { Save(Destionation, false); } public void Save(string Destination, bool Overwrite) { byte[] theForwarder = ToByteArray(); if (Path.HasExtension(Destination) == false) Destination += ".dol"; if (File.Exists(Destination)) { if (Overwrite == true) File.Delete(Destination); else throw new Exception("The destination file already exists!"); } using (FileStream fs = new FileStream(Destination, FileMode.Create)) { fs.Write(theForwarder, 0, theForwarder.Length); } } public byte[] ToByteArray() { MemoryStream ms = this.ToMemoryStream(); return ms.ToArray(); } public MemoryStream ToMemoryStream() { MemoryStream BaseStream = GetBase(); MemoryStream TailStream = GetTail(); BaseStream = ConvertBase(BaseStream); TailStream = EditTailFolder(TailStream); byte[] BaseArray = BaseStream.ToArray(); byte[] TailArray = TailStream.ToArray(); MemoryStream Result = new MemoryStream(); Result.Seek(0, SeekOrigin.End); Result.Write(BaseArray, 0, BaseArray.Length); Result.Write(TailArray, 0, TailArray.Length); return Result; } private MemoryStream EditTailFolder(MemoryStream TailStream) { char[] FolderChars = thisAppFolder.ToCharArray(); int[] Offsets = GetOffsets(FolderChars.Length); TailStream.Seek(1, SeekOrigin.Begin); foreach (char thisChar in FolderChars) TailStream.WriteByte((byte)thisChar); TailStream.Seek(Offsets[0], SeekOrigin.Begin); foreach (char thisChar in FolderChars) TailStream.WriteByte((byte)thisChar); TailStream.Seek(Offsets[1], SeekOrigin.Begin); foreach (char thisChar in FolderChars) TailStream.WriteByte((byte)thisChar); if (toElf == true) TailStream = EditTailToElf(TailStream); return TailStream; } private MemoryStream EditTailToElf(MemoryStream TailStream) { int[] Offsets = GetDolOffsets(thisAppFolder.Length); byte[] Elf = new byte[] { 0x65, 0x6c, 0x66 }; foreach (int thisOffset in Offsets) { TailStream.Seek(thisOffset, SeekOrigin.Begin); TailStream.Write(Elf, 0, Elf.Length); } return TailStream; } private int[] GetDolOffsets(int CharCount) { int[] Offsets = new int[5]; switch (CharCount) { case 3: Offsets[0] = 10; Offsets[1] = 25; Offsets[2] = 87; Offsets[3] = 336; Offsets[4] = 344; break; case 4: Offsets[0] = 11; Offsets[1] = 25; Offsets[2] = 87; Offsets[3] = 336; Offsets[4] = 344; break; case 5: Offsets[0] = 12; Offsets[1] = 25; Offsets[2] = 91; Offsets[3] = 340; Offsets[4] = 348; break; case 6: Offsets[0] = 13; Offsets[1] = 29; Offsets[2] = 95; Offsets[3] = 348; Offsets[4] = 356; break; case 7: Offsets[0] = 14; Offsets[1] = 29; Offsets[2] = 95; Offsets[3] = 348; Offsets[4] = 356; break; case 8: Offsets[0] = 15; Offsets[1] = 29; Offsets[2] = 95; Offsets[3] = 348; Offsets[4] = 356; break; case 9: Offsets[0] = 16; Offsets[1] = 29; Offsets[2] = 99; Offsets[3] = 352; Offsets[4] = 360; break; case 10: Offsets[0] = 17; Offsets[1] = 33; Offsets[2] = 103; Offsets[3] = 360; Offsets[4] = 368; break; case 11: Offsets[0] = 18; Offsets[1] = 33; Offsets[2] = 103; Offsets[3] = 360; Offsets[4] = 368; break; case 12: Offsets[0] = 19; Offsets[1] = 33; Offsets[2] = 103; Offsets[3] = 360; Offsets[4] = 368; break; case 13: Offsets[0] = 20; Offsets[1] = 33; Offsets[2] = 107; Offsets[3] = 364; Offsets[4] = 372; break; case 14: Offsets[0] = 21; Offsets[1] = 37; Offsets[2] = 111; Offsets[3] = 372; Offsets[4] = 380; break; case 15: Offsets[0] = 22; Offsets[1] = 37; Offsets[2] = 11; Offsets[3] = 372; Offsets[4] = 380; break; case 16: Offsets[0] = 23; Offsets[1] = 37; Offsets[2] = 111; Offsets[3] = 372; Offsets[4] = 380; break; case 17: Offsets[0] = 24; Offsets[1] = 37; Offsets[2] = 115; Offsets[3] = 376; Offsets[4] = 384; break; case 18: Offsets[0] = 25; Offsets[1] = 41; Offsets[2] = 119; Offsets[3] = 384; Offsets[4] = 392; break; default: throw new Exception(); } return Offsets; } private int[] GetOffsets(int CharCount) { int First = 0; int Second = 0; switch (CharCount) { case 3: case 4: First = 57; Second = 100; break; case 5: First = 57; Second = 104; break; case 6: case 7: case 8: First = 61; Second = 108; break; case 9: First = 61; Second = 112; break; case 10: case 11: case 12: case 13: First = 65; Second = 120; break; case 14: case 15: case 16: First = 69; Second = 124; break; case 17: First = 69; Second = 128; break; case 18: First = 73; Second = 132; break; default: throw new Exception(); } return new int[] { First, Second }; } private MemoryStream GetBase() { switch (thisAppFolder.Length) { case 3: case 4: case 5: return GetReourceStream("ForwardMii.Resources.SDSDHC.3CharsBase.bin"); case 6: case 7: case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16: return GetReourceStream("ForwardMii.Resources.SDSDHC.6CharsBase.bin"); case 17: case 18: return GetReourceStream("ForwardMii.Resources.SDSDHC.17CharsBase.bin"); default: throw new Exception(); } } private MemoryStream GetTail() { switch (thisAppFolder.Length) { case 3: return GetReourceStream("ForwardMii.Resources.SDSDHC.3CharsTail.bin"); case 4: return GetReourceStream("ForwardMii.Resources.SDSDHC.4CharsTail.bin"); case 5: return GetReourceStream("ForwardMii.Resources.SDSDHC.5CharsTail.bin"); case 6: return GetReourceStream("ForwardMii.Resources.SDSDHC.6CharsTail.bin"); case 7: return GetReourceStream("ForwardMii.Resources.SDSDHC.7CharsTail.bin"); case 8: return GetReourceStream("ForwardMii.Resources.SDSDHC.8CharsTail.bin"); case 9: return GetReourceStream("ForwardMii.Resources.SDSDHC.9CharsTail.bin"); case 10: return GetReourceStream("ForwardMii.Resources.SDSDHC.10CharsTail.bin"); case 11: return GetReourceStream("ForwardMii.Resources.SDSDHC.11CharsTail.bin"); case 12: return GetReourceStream("ForwardMii.Resources.SDSDHC.12CharsTail.bin"); case 13: return GetReourceStream("ForwardMii.Resources.SDSDHC.13CharsTail.bin"); case 14: return GetReourceStream("ForwardMii.Resources.SDSDHC.14CharsTail.bin"); case 15: return GetReourceStream("ForwardMii.Resources.SDSDHC.15CharsTail.bin"); case 16: return GetReourceStream("ForwardMii.Resources.SDSDHC.16CharsTail.bin"); case 17: return GetReourceStream("ForwardMii.Resources.SDSDHC.17CharsTail.bin"); case 18: return GetReourceStream("ForwardMii.Resources.SDSDHC.18CharsTail.bin"); default: throw new Exception(); } } private MemoryStream ConvertBase(MemoryStream BaseStream) { switch (thisAppFolder.Length) { case 3: return BaseStream; case 4: return BaseStream; case 5: return SDSDHC_ConvertBaseStream.ConvertTo5Chars(BaseStream); case 6: return BaseStream; case 7: return BaseStream; case 8: return BaseStream; case 9: return SDSDHC_ConvertBaseStream.ConvertTo9Chars(BaseStream); case 10: return SDSDHC_ConvertBaseStream.ConvertTo10Chars(BaseStream); case 11: return SDSDHC_ConvertBaseStream.ConvertTo10Chars(BaseStream); case 12: return SDSDHC_ConvertBaseStream.ConvertTo10Chars(BaseStream); case 13: return SDSDHC_ConvertBaseStream.ConvertTo13Chars(BaseStream); case 14: return SDSDHC_ConvertBaseStream.ConvertTo14Chars(BaseStream); case 15: return SDSDHC_ConvertBaseStream.ConvertTo14Chars(BaseStream); case 16: return SDSDHC_ConvertBaseStream.ConvertTo14Chars(BaseStream); case 17: return BaseStream; case 18: return SDSDHC_ConvertBaseStream.ConvertTo18Chars(BaseStream); default: throw new Exception(); } } private MemoryStream GetReourceStream(string theResource) { Stream thisStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(theResource); byte[] thisArray = new byte[thisStream.Length]; thisStream.Read(thisArray, 0, thisArray.Length); return new MemoryStream(thisArray); } } }