customizemii/ForwardMii/ForwardMii_SDSDHC.cs

440 lines
15 KiB
C#

/* 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 <http://www.gnu.org/licenses/>.
*/
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);
}
}
}