diff --git a/CommonKey.cs b/CommonKey.cs
index ad04749..573f34b 100644
--- a/CommonKey.cs
+++ b/CommonKey.cs
@@ -1,18 +1,30 @@
-// Decompiled with JetBrains decompiler
-// Type: libWiiSharp.CommonKey
-// Assembly: libWiiSharp, Version=0.4.0.0, Culture=neutral, PublicKeyToken=null
-// MVID: FBF36F3D-B5D6-481F-B5F5-1BD3C19E13B2
-// Assembly location: C:\Users\theso\Downloads\NCPatcher\pack\libWiiSharp.dll
+/* This file is part of libWiiSharp
+ * Copyright (C) 2009 Leathl
+ * Copyright (C) 2020 Github Contributors
+ *
+ * libWiiSharp 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.
+ *
+ * libWiiSharp 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 .
+ */
namespace libWiiSharp
{
- public class CommonKey
- {
- private static string standardKey = "ebe42a225e8593e448d9c5457381aaf7";
- private static string koreanKey = "63b82bb4f4614e2e13f2fefbba4c9b7e";
+ public class CommonKey
+ {
+ private static string standardKey = "ebe42a225e8593e448d9c5457381aaf7";
+ private static string koreanKey = "63b82bb4f4614e2e13f2fefbba4c9b7e";
- public static byte[] GetStandardKey() => Shared.HexStringToByteArray(CommonKey.standardKey);
+ public static byte[] GetStandardKey() => Shared.HexStringToByteArray(CommonKey.standardKey);
- public static byte[] GetKoreanKey() => Shared.HexStringToByteArray(CommonKey.koreanKey);
- }
+ public static byte[] GetKoreanKey() => Shared.HexStringToByteArray(CommonKey.koreanKey);
+ }
}
diff --git a/CommonKeyType.cs b/CommonKeyType.cs
deleted file mode 100644
index b5d75c2..0000000
--- a/CommonKeyType.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-// Decompiled with JetBrains decompiler
-// Type: libWiiSharp.CommonKeyType
-// Assembly: libWiiSharp, Version=0.4.0.0, Culture=neutral, PublicKeyToken=null
-// MVID: FBF36F3D-B5D6-481F-B5F5-1BD3C19E13B2
-// Assembly location: C:\Users\theso\Downloads\NCPatcher\pack\libWiiSharp.dll
-
-namespace libWiiSharp
-{
- public enum CommonKeyType : byte
- {
- Standard,
- Korean,
- }
-}
diff --git a/ContentIndices.cs b/ContentIndices.cs
index 57d3075..4750e57 100644
--- a/ContentIndices.cs
+++ b/ContentIndices.cs
@@ -1,8 +1,20 @@
-// Decompiled with JetBrains decompiler
-// Type: libWiiSharp.ContentIndices
-// Assembly: libWiiSharp, Version=0.4.0.0, Culture=neutral, PublicKeyToken=null
-// MVID: FBF36F3D-B5D6-481F-B5F5-1BD3C19E13B2
-// Assembly location: C:\Users\theso\Downloads\NCPatcher\pack\libWiiSharp.dll
+/* This file is part of libWiiSharp
+ * Copyright (C) 2009 Leathl
+ * Copyright (C) 2020 Github Contributors
+ *
+ * libWiiSharp 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.
+ *
+ * libWiiSharp 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;
diff --git a/HbcTransmitter.cs b/HbcTransmitter.cs
index 3460f9f..5a634b9 100644
--- a/HbcTransmitter.cs
+++ b/HbcTransmitter.cs
@@ -1,301 +1,415 @@
-// Decompiled with JetBrains decompiler
-// Type: libWiiSharp.HbcTransmitter
-// Assembly: libWiiSharp, Version=0.4.0.0, Culture=neutral, PublicKeyToken=null
-// MVID: FBF36F3D-B5D6-481F-B5F5-1BD3C19E13B2
-// Assembly location: C:\Users\theso\Downloads\NCPatcher\pack\libWiiSharp.dll
+/* This file is part of libWiiSharp
+ * Copyright (C) 2009 Leathl
+ * Copyright (C) 2020 Github Contributors
+ *
+ * libWiiSharp 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.
+ *
+ * libWiiSharp 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.ComponentModel;
using System.IO;
using System.Net.Sockets;
+using System.Runtime.InteropServices;
namespace libWiiSharp
{
- public class HbcTransmitter : IDisposable
- {
- private int blocksize = 4096;
- private int wiiloadMayor;
- private int wiiloadMinor = 5;
- private bool compress;
- private string ipAddress;
- private int port = 4299;
- private string lastErrorMessage = string.Empty;
- private Protocol protocol;
- private TcpClient tcpClient;
- private NetworkStream nwStream;
- private string lastError = string.Empty;
- private int transmittedLength;
- private int compressionRatio;
- private bool isDisposed;
-
- public int Blocksize
+ public enum Protocol
{
- get => this.blocksize;
- set => this.blocksize = value;
+ ///
+ /// Will preconfigure all settings for HBC to 1.0.5 (HAXX).
+ ///
+ HAXX = 0,
+ ///
+ /// Will preconfigure all settings for HBC from 1.0.5 (JODI).
+ ///
+ JODI = 1,
+ ///
+ /// Remember to define your custom settings.
+ ///
+ Custom = 2,
}
- public int WiiloadVersionMayor
+ ///
+ /// The HbcTransmitter can easily transmit files to the Homebrew Channel.
+ /// In order to use compression, you need zlib1.dll in the application directory.
+ ///
+ public class HbcTransmitter : IDisposable
{
- get => this.wiiloadMayor;
- set => this.wiiloadMayor = value;
- }
+ private int blocksize = 4096;
+ private int wiiloadMayor;
+ private int wiiloadMinor = 5;
+ private bool compress;
+ private string ipAddress;
+ private int port = 4299;
+ private string lastErrorMessage = string.Empty;
+ private Protocol protocol;
+ private TcpClient tcpClient;
+ private NetworkStream nwStream;
+ private string lastError = string.Empty;
+ private int transmittedLength;
+ private int compressionRatio;
+ private bool isDisposed;
- public int WiiloadVersionMinor
- {
- get => this.wiiloadMinor;
- set => this.wiiloadMinor = value;
- }
-
- public bool Compress
- {
- get => this.compress;
- set
- {
- if (this.protocol == Protocol.HAXX)
- return;
- this.compress = value;
- }
- }
-
- public string IpAddress
- {
- get => this.ipAddress;
- set => this.ipAddress = value;
- }
-
- public int Port
- {
- get => this.port;
- set => this.port = value;
- }
-
- public int TransmittedLength => this.transmittedLength;
-
- public int CompressionRatio => this.compressionRatio;
-
- public string LastError => this.lastError;
-
- public event EventHandler Progress;
-
- public event EventHandler Debug;
-
- public HbcTransmitter(Protocol protocol, string ipAddress)
- {
- this.protocol = protocol;
- this.ipAddress = ipAddress;
- this.wiiloadMinor = protocol == Protocol.HAXX ? 4 : 5;
- this.compress = protocol == Protocol.JODI;
- }
-
- ~HbcTransmitter() => this.Dispose(false);
-
- public void Dispose()
- {
- this.Dispose(true);
- GC.SuppressFinalize((object) this);
- }
-
- protected virtual void Dispose(bool disposing)
- {
- if (disposing && !this.isDisposed)
- {
- this.ipAddress = (string) null;
- this.lastErrorMessage = (string) null;
- this.lastError = (string) null;
- if (this.nwStream != null)
+ ///
+ /// The size of the buffer that is used to transmit the data.
+ /// Default is 4 * 1024. If you're facing problems (freezes while transmitting), try a higher size.
+ ///
+ public int Blocksize
{
- this.nwStream.Close();
- this.nwStream = (NetworkStream) null;
+ get => this.blocksize;
+ set => this.blocksize = value;
}
- if (this.tcpClient != null)
+
+ ///
+ /// The mayor version of wiiload. You might need to change it for upcoming releases of the HBC.
+ ///
+ public int WiiloadVersionMayor
{
- this.tcpClient.Close();
- this.tcpClient = (TcpClient) null;
+ get => this.wiiloadMayor;
+ set => this.wiiloadMayor = value;
}
- }
- this.isDisposed = true;
+
+ ///
+ /// The minor version of wiiload. You might need to change it for upcoming releases of the HBC.
+ ///
+ public int WiiloadVersionMinor
+ {
+ get => this.wiiloadMinor;
+ set => this.wiiloadMinor = value;
+ }
+
+ ///
+ /// If true, the data will be compressed before being transmitted. NOT available for Protocol.HAXX!
+ /// Also, compression will only work if zlib1.dll is in the application folder.
+ ///
+ public bool Compress
+ {
+ get => this.compress;
+ set
+ {
+ if (this.protocol == Protocol.HAXX)
+ return;
+ this.compress = value;
+ }
+ }
+
+ ///
+ /// The IP address of the Wii.
+ ///
+ public string IpAddress
+ {
+ get => this.ipAddress;
+ set => this.ipAddress = value;
+ }
+
+ /// The port used for the transmission.
+ /// You don't need to touch this unless the port changes in future releases of the HBC.
+ ///
+ public int Port
+ {
+ get => this.port;
+ set => this.port = value;
+ }
+
+ ///
+ /// After a successfully completed transmission, this value holds the number of transmitted bytes.
+ ///
+ public int TransmittedLength => this.transmittedLength;
+
+ ///
+ /// After a successfully completed transmission, this value holds the compression ratio.
+ /// Will be 0 if the data wasn't compressed.
+ ///
+ public int CompressionRatio => this.compressionRatio;
+
+ ///
+ /// Holds the last occured error message.
+ ///
+ public string LastError => this.lastError;
+
+ public HbcTransmitter(Protocol protocol, string ipAddress)
+ {
+ this.protocol = protocol;
+ this.ipAddress = ipAddress;
+ this.wiiloadMinor = protocol == Protocol.HAXX ? 4 : 5;
+ this.compress = protocol == Protocol.JODI;
+ }
+
+ #region IDisposable Members
+
+ ~HbcTransmitter() => this.Dispose(false);
+
+ public void Dispose()
+ {
+ this.Dispose(true);
+ GC.SuppressFinalize((object) this);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (disposing && !this.isDisposed)
+ {
+ this.ipAddress = (string) null;
+ this.lastErrorMessage = (string) null;
+ this.lastError = (string) null;
+ if (this.nwStream != null)
+ {
+ this.nwStream.Close();
+ this.nwStream = (NetworkStream) null;
+ }
+ if (this.tcpClient != null)
+ {
+ this.tcpClient.Close();
+ this.tcpClient = (TcpClient) null;
+ }
+ }
+ this.isDisposed = true;
+ }
+ #endregion
+
+ #region Public Functions
+ public bool TransmitFile(string pathToFile) => this.transmit(Path.GetFileName(pathToFile), File.ReadAllBytes(pathToFile));
+
+ public bool TransmitFile(string fileName, byte[] fileData) => this.transmit(fileName, fileData);
+ #endregion
+
+ #region Private Functions
+ private bool transmit(string fileName, byte[] fileData)
+ {
+ this.fireDebug("Transmitting {0} to {1}:{2}...", (object) fileName, (object) this.ipAddress, (object) this.port);
+ if (!Environment.OSVersion.ToString().ToLower().Contains("windows"))
+ this.compress = false;
+ if (fileName.ToLower().EndsWith(".zip"))
+ this.compress = false;
+ this.tcpClient = new TcpClient();
+ byte[] buffer1 = new byte[4];
+ this.fireDebug(" Connecting...");
+ try
+ {
+ this.tcpClient.Connect(this.ipAddress, 4299);
+ }
+ catch (Exception ex)
+ {
+ this.fireDebug(" -> Connection Failed:\n" + ex.Message);
+ this.lastError = "Connection Failed:\n" + ex.Message;
+ this.tcpClient.Close();
+ return false;
+ }
+ this.nwStream = this.tcpClient.GetStream();
+ this.fireDebug(" Sending Magic...");
+ buffer1[0] = (byte) 72;
+ buffer1[1] = (byte) 65;
+ buffer1[2] = (byte) 88;
+ buffer1[3] = (byte) 88;
+ try
+ {
+ this.nwStream.Write(buffer1, 0, 4);
+ }
+ catch (Exception ex)
+ {
+ this.fireDebug(" -> Error sending Magic:\n" + ex.Message);
+ this.lastError = "Error sending Magic:\n" + ex.Message;
+ this.nwStream.Close();
+ this.tcpClient.Close();
+ return false;
+ }
+ this.fireDebug(" Sending Version Info...");
+ buffer1[0] = (byte) this.wiiloadMayor;
+ buffer1[1] = (byte) this.wiiloadMinor;
+ buffer1[2] = (byte) (fileName.Length + 2 >> 8 & (int) byte.MaxValue);
+ buffer1[3] = (byte) (fileName.Length + 2 & (int) byte.MaxValue);
+ try
+ {
+ this.nwStream.Write(buffer1, 0, 4);
+ }
+ catch (Exception ex)
+ {
+ this.fireDebug(" -> Error sending Version Info:\n" + ex.Message);
+ this.lastError = "Error sending Version Info:\n" + ex.Message;
+ this.nwStream.Close();
+ this.tcpClient.Close();
+ return false;
+ }
+ byte[] buffer2;
+ if (this.compress)
+ {
+ this.fireDebug(" Compressing File...");
+ try
+ {
+ buffer2 = zlibWrapper.Compress(fileData);
+ }
+ catch
+ {
+ this.fireDebug(" -> Compression failed, continuing without compression...");
+ this.compress = false;
+ buffer2 = fileData;
+ fileData = new byte[0];
+ }
+ }
+ else
+ {
+ buffer2 = fileData;
+ fileData = new byte[0];
+ }
+ this.fireDebug(" Sending Filesize...");
+ buffer1[0] = (byte) (buffer2.Length >> 24 & (int) byte.MaxValue);
+ buffer1[1] = (byte) (buffer2.Length >> 16 & (int) byte.MaxValue);
+ buffer1[2] = (byte) (buffer2.Length >> 8 & (int) byte.MaxValue);
+ buffer1[3] = (byte) (buffer2.Length & (int) byte.MaxValue);
+ try
+ {
+ this.nwStream.Write(buffer1, 0, 4);
+ }
+ catch (Exception ex)
+ {
+ this.fireDebug(" -> Error sending Filesize:\n" + ex.Message);
+ this.lastError = "Error sending Filesize:\n" + ex.Message;
+ this.nwStream.Close();
+ this.tcpClient.Close();
+ return false;
+ }
+ if (this.protocol != Protocol.HAXX)
+ {
+ buffer1[0] = (byte) (fileData.Length >> 24 & (int) byte.MaxValue);
+ buffer1[1] = (byte) (fileData.Length >> 16 & (int) byte.MaxValue);
+ buffer1[2] = (byte) (fileData.Length >> 8 & (int) byte.MaxValue);
+ buffer1[3] = (byte) (fileData.Length & (int) byte.MaxValue);
+ try
+ {
+ this.nwStream.Write(buffer1, 0, 4);
+ }
+ catch (Exception ex)
+ {
+ this.fireDebug(" -> Error sending Filesize:\n" + ex.Message);
+ this.lastError = "Error sending Filesize:\n" + ex.Message;
+ this.nwStream.Close();
+ this.tcpClient.Close();
+ return false;
+ }
+ }
+ this.fireDebug(" Sending File...");
+ int offset = 0;
+ int num1 = 0;
+ int num2 = buffer2.Length / this.Blocksize;
+ int num3 = buffer2.Length % this.Blocksize;
+ try
+ {
+ do
+ {
+ this.fireProgress(++num1 * 100 / num2);
+ this.nwStream.Write(buffer2, offset, this.Blocksize);
+ offset += this.Blocksize;
+ }
+ while (num1 < num2);
+ if (num3 > 0)
+ this.nwStream.Write(buffer2, offset, buffer2.Length - offset);
+ }
+ catch (Exception ex)
+ {
+ this.fireDebug(" -> Error sending File:\n" + ex.Message);
+ this.lastError = "Error sending File:\n" + ex.Message;
+ this.nwStream.Close();
+ this.tcpClient.Close();
+ return false;
+ }
+ this.fireDebug(" Sending Arguments...");
+ byte[] buffer3 = new byte[fileName.Length + 2];
+ for (int index = 0; index < fileName.Length; ++index)
+ buffer3[index] = (byte) fileName.ToCharArray()[index];
+ try
+ {
+ this.nwStream.Write(buffer3, 0, buffer3.Length);
+ }
+ catch (Exception ex)
+ {
+ this.fireDebug(" -> Error sending Arguments:\n" + ex.Message);
+ this.lastError = "Error sending Arguments:\n" + ex.Message;
+ this.nwStream.Close();
+ this.tcpClient.Close();
+ return false;
+ }
+ this.nwStream.Close();
+ this.tcpClient.Close();
+ this.transmittedLength = buffer2.Length;
+ this.compressionRatio = !this.compress || fileData.Length == 0 ? 0 : buffer2.Length * 100 / fileData.Length;
+ this.fireDebug("Transmitting {0} to {1}:{2} Finished...", (object) fileName, (object) this.ipAddress, (object) this.port);
+ return true;
+ }
+ #endregion
+
+ #region Events
+ ///
+ /// Fires the Progress of various operations
+ ///
+ public event EventHandler Progress;
+
+ ///
+ /// Fires debugging messages. You may write them into a log file or log textbox.
+ ///
+ public event EventHandler Debug;
+
+ private void fireDebug(string debugMessage, params object[] args)
+ {
+ EventHandler debug = this.Debug;
+ if (debug == null)
+ return;
+ debug(new object(), new MessageEventArgs(string.Format(debugMessage, args)));
+ }
+
+ private void fireProgress(int progressPercentage)
+ {
+ EventHandler progress = this.Progress;
+ if (progress == null)
+ return;
+ progress(new object(), new ProgressChangedEventArgs(progressPercentage, (object) string.Empty));
+ }
+ #endregion
}
- public bool TransmitFile(string pathToFile) => this.transmit(Path.GetFileName(pathToFile), File.ReadAllBytes(pathToFile));
-
- public bool TransmitFile(string fileName, byte[] fileData) => this.transmit(fileName, fileData);
-
- private bool transmit(string fileName, byte[] fileData)
+ internal class zlibWrapper
{
- this.fireDebug("Transmitting {0} to {1}:{2}...", (object) fileName, (object) this.ipAddress, (object) this.port);
- if (!Environment.OSVersion.ToString().ToLower().Contains("windows"))
- this.compress = false;
- if (fileName.ToLower().EndsWith(".zip"))
- this.compress = false;
- this.tcpClient = new TcpClient();
- byte[] buffer1 = new byte[4];
- this.fireDebug(" Connecting...");
- try
- {
- this.tcpClient.Connect(this.ipAddress, 4299);
- }
- catch (Exception ex)
- {
- this.fireDebug(" -> Connection Failed:\n" + ex.Message);
- this.lastError = "Connection Failed:\n" + ex.Message;
- this.tcpClient.Close();
- return false;
- }
- this.nwStream = this.tcpClient.GetStream();
- this.fireDebug(" Sending Magic...");
- buffer1[0] = (byte) 72;
- buffer1[1] = (byte) 65;
- buffer1[2] = (byte) 88;
- buffer1[3] = (byte) 88;
- try
- {
- this.nwStream.Write(buffer1, 0, 4);
- }
- catch (Exception ex)
- {
- this.fireDebug(" -> Error sending Magic:\n" + ex.Message);
- this.lastError = "Error sending Magic:\n" + ex.Message;
- this.nwStream.Close();
- this.tcpClient.Close();
- return false;
- }
- this.fireDebug(" Sending Version Info...");
- buffer1[0] = (byte) this.wiiloadMayor;
- buffer1[1] = (byte) this.wiiloadMinor;
- buffer1[2] = (byte) (fileName.Length + 2 >> 8 & (int) byte.MaxValue);
- buffer1[3] = (byte) (fileName.Length + 2 & (int) byte.MaxValue);
- try
- {
- this.nwStream.Write(buffer1, 0, 4);
- }
- catch (Exception ex)
- {
- this.fireDebug(" -> Error sending Version Info:\n" + ex.Message);
- this.lastError = "Error sending Version Info:\n" + ex.Message;
- this.nwStream.Close();
- this.tcpClient.Close();
- return false;
- }
- byte[] buffer2;
- if (this.compress)
- {
- this.fireDebug(" Compressing File...");
- try
+ [DllImport("zlib1.dll")]
+ private static extern zlibWrapper.ZLibError compress2(
+ byte[] dest,
+ ref int destLength,
+ byte[] source,
+ int sourceLength,
+ int level);
+
+ public static byte[] Compress(byte[] inFile)
{
- buffer2 = zlibWrapper.Compress(fileData);
+ byte[] array = new byte[inFile.Length + 64];
+ int destLength = -1;
+ zlibWrapper.ZLibError zlibError = zlibWrapper.compress2(array, ref destLength, inFile, inFile.Length, 6);
+ if (zlibError != zlibWrapper.ZLibError.Z_OK || destLength <= -1 || destLength >= inFile.Length)
+ throw new Exception("An error occured while compressing! Code: " + zlibError.ToString());
+ Array.Resize(ref array, destLength);
+ return array;
}
- catch
+
+ public enum ZLibError
{
- this.fireDebug(" -> Compression failed, continuing without compression...");
- this.compress = false;
- buffer2 = fileData;
- fileData = new byte[0];
+ Z_VERSION_ERROR = -6, // 0xFFFFFFFA
+ Z_BUF_ERROR = -5, // 0xFFFFFFFB
+ Z_MEM_ERROR = -4, // 0xFFFFFFFC
+ Z_DATA_ERROR = -3, // 0xFFFFFFFD
+ Z_STREAM_ERROR = -2, // 0xFFFFFFFE
+ Z_ERRNO = -1, // 0xFFFFFFFF
+ Z_OK = 0,
+ Z_STREAM_END = 1,
+ Z_NEED_DICT = 2,
}
- }
- else
- {
- buffer2 = fileData;
- fileData = new byte[0];
- }
- this.fireDebug(" Sending Filesize...");
- buffer1[0] = (byte) (buffer2.Length >> 24 & (int) byte.MaxValue);
- buffer1[1] = (byte) (buffer2.Length >> 16 & (int) byte.MaxValue);
- buffer1[2] = (byte) (buffer2.Length >> 8 & (int) byte.MaxValue);
- buffer1[3] = (byte) (buffer2.Length & (int) byte.MaxValue);
- try
- {
- this.nwStream.Write(buffer1, 0, 4);
- }
- catch (Exception ex)
- {
- this.fireDebug(" -> Error sending Filesize:\n" + ex.Message);
- this.lastError = "Error sending Filesize:\n" + ex.Message;
- this.nwStream.Close();
- this.tcpClient.Close();
- return false;
- }
- if (this.protocol != Protocol.HAXX)
- {
- buffer1[0] = (byte) (fileData.Length >> 24 & (int) byte.MaxValue);
- buffer1[1] = (byte) (fileData.Length >> 16 & (int) byte.MaxValue);
- buffer1[2] = (byte) (fileData.Length >> 8 & (int) byte.MaxValue);
- buffer1[3] = (byte) (fileData.Length & (int) byte.MaxValue);
- try
- {
- this.nwStream.Write(buffer1, 0, 4);
- }
- catch (Exception ex)
- {
- this.fireDebug(" -> Error sending Filesize:\n" + ex.Message);
- this.lastError = "Error sending Filesize:\n" + ex.Message;
- this.nwStream.Close();
- this.tcpClient.Close();
- return false;
- }
- }
- this.fireDebug(" Sending File...");
- int offset = 0;
- int num1 = 0;
- int num2 = buffer2.Length / this.Blocksize;
- int num3 = buffer2.Length % this.Blocksize;
- try
- {
- do
- {
- this.fireProgress(++num1 * 100 / num2);
- this.nwStream.Write(buffer2, offset, this.Blocksize);
- offset += this.Blocksize;
- }
- while (num1 < num2);
- if (num3 > 0)
- this.nwStream.Write(buffer2, offset, buffer2.Length - offset);
- }
- catch (Exception ex)
- {
- this.fireDebug(" -> Error sending File:\n" + ex.Message);
- this.lastError = "Error sending File:\n" + ex.Message;
- this.nwStream.Close();
- this.tcpClient.Close();
- return false;
- }
- this.fireDebug(" Sending Arguments...");
- byte[] buffer3 = new byte[fileName.Length + 2];
- for (int index = 0; index < fileName.Length; ++index)
- buffer3[index] = (byte) fileName.ToCharArray()[index];
- try
- {
- this.nwStream.Write(buffer3, 0, buffer3.Length);
- }
- catch (Exception ex)
- {
- this.fireDebug(" -> Error sending Arguments:\n" + ex.Message);
- this.lastError = "Error sending Arguments:\n" + ex.Message;
- this.nwStream.Close();
- this.tcpClient.Close();
- return false;
- }
- this.nwStream.Close();
- this.tcpClient.Close();
- this.transmittedLength = buffer2.Length;
- this.compressionRatio = !this.compress || fileData.Length == 0 ? 0 : buffer2.Length * 100 / fileData.Length;
- this.fireDebug("Transmitting {0} to {1}:{2} Finished...", (object) fileName, (object) this.ipAddress, (object) this.port);
- return true;
}
- private void fireDebug(string debugMessage, params object[] args)
- {
- EventHandler debug = this.Debug;
- if (debug == null)
- return;
- debug(new object(), new MessageEventArgs(string.Format(debugMessage, args)));
- }
-
- private void fireProgress(int progressPercentage)
- {
- EventHandler progress = this.Progress;
- if (progress == null)
- return;
- progress(new object(), new ProgressChangedEventArgs(progressPercentage, (object) string.Empty));
- }
- }
}
diff --git a/Headers.cs b/Headers.cs
index 8018362..361d07c 100644
--- a/Headers.cs
+++ b/Headers.cs
@@ -1,8 +1,20 @@
-// Decompiled with JetBrains decompiler
-// Type: libWiiSharp.Headers
-// Assembly: libWiiSharp, Version=0.4.0.0, Culture=neutral, PublicKeyToken=null
-// MVID: FBF36F3D-B5D6-481F-B5F5-1BD3C19E13B2
-// Assembly location: C:\Users\theso\Downloads\NCPatcher\pack\libWiiSharp.dll
+/* This file is part of libWiiSharp
+ * Copyright (C) 2009 Leathl
+ * Copyright (C) 2020 Github Contributors
+ *
+ * libWiiSharp 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.
+ *
+ * libWiiSharp 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;
@@ -10,581 +22,773 @@ using System.Security.Cryptography;
namespace libWiiSharp
{
- public class Headers
- {
- private static uint imd5Magic = 1229800501;
- private static uint imetMagic = 1229800788;
-
- public static Headers.HeaderType DetectHeader(string pathToFile) => Headers.DetectHeader(File.ReadAllBytes(pathToFile));
-
- public static Headers.HeaderType DetectHeader(byte[] file)
+ public class Headers
{
- if (file.Length > 68 && (int) Shared.Swap(BitConverter.ToUInt32(file, 64)) == (int) Headers.imetMagic)
- return Headers.HeaderType.ShortIMET;
- if (file.Length > 132 && (int) Shared.Swap(BitConverter.ToUInt32(file, 128)) == (int) Headers.imetMagic)
- return Headers.HeaderType.IMET;
- return file.Length > 4 && (int) Shared.Swap(BitConverter.ToUInt32(file, 0)) == (int) Headers.imd5Magic ? Headers.HeaderType.IMD5 : Headers.HeaderType.None;
- }
+ private static uint imd5Magic = 1229800501;
+ private static uint imetMagic = 1229800788;
- public static Headers.HeaderType DetectHeader(Stream file)
- {
- byte[] buffer = new byte[4];
- if (file.Length > 68L)
- {
- file.Seek(64L, SeekOrigin.Begin);
- file.Read(buffer, 0, buffer.Length);
- if ((int) Shared.Swap(BitConverter.ToUInt32(buffer, 0)) == (int) Headers.imetMagic)
- return Headers.HeaderType.ShortIMET;
- }
- if (file.Length > 132L)
- {
- file.Seek(128L, SeekOrigin.Begin);
- file.Read(buffer, 0, buffer.Length);
- if ((int) Shared.Swap(BitConverter.ToUInt32(buffer, 0)) == (int) Headers.imetMagic)
- return Headers.HeaderType.IMET;
- }
- if (file.Length > 4L)
- {
- file.Seek(0L, SeekOrigin.Begin);
- file.Read(buffer, 0, buffer.Length);
- if ((int) Shared.Swap(BitConverter.ToUInt32(buffer, 0)) == (int) Headers.imd5Magic)
- return Headers.HeaderType.IMD5;
- }
- return Headers.HeaderType.None;
- }
-
- public enum HeaderType
- {
- None = 0,
- IMD5 = 32, // 0x00000020
- ShortIMET = 1536, // 0x00000600
- IMET = 1600, // 0x00000640
- }
-
- public class IMET
- {
- private bool hashesMatch = true;
- private bool isShortImet;
- private byte[] additionalPadding = new byte[64];
- private byte[] padding = new byte[64];
- private uint imetMagic = 1229800788;
- private uint sizeOfHeader = 1536;
- private uint unknown = 3;
- private uint iconSize;
- private uint bannerSize;
- private uint soundSize;
- private uint flags;
- private byte[] japaneseTitle = new byte[84];
- private byte[] englishTitle = new byte[84];
- private byte[] germanTitle = new byte[84];
- private byte[] frenchTitle = new byte[84];
- private byte[] spanishTitle = new byte[84];
- private byte[] italianTitle = new byte[84];
- private byte[] dutchTitle = new byte[84];
- private byte[] unknownTitle1 = new byte[84];
- private byte[] unknownTitle2 = new byte[84];
- private byte[] koreanTitle = new byte[84];
- private byte[] padding2 = new byte[588];
- private byte[] hash = new byte[16];
-
- public bool IsShortIMET
- {
- get => this.isShortImet;
- set => this.isShortImet = value;
- }
-
- public uint IconSize
- {
- get => this.iconSize;
- set => this.iconSize = value;
- }
-
- public uint BannerSize
- {
- get => this.bannerSize;
- set => this.bannerSize = value;
- }
-
- public uint SoundSize
- {
- get => this.soundSize;
- set => this.soundSize = value;
- }
-
- public string JapaneseTitle
- {
- get => this.returnTitleAsString(this.japaneseTitle);
- set => this.setTitleFromString(value, 0);
- }
-
- public string EnglishTitle
- {
- get => this.returnTitleAsString(this.englishTitle);
- set => this.setTitleFromString(value, 1);
- }
-
- public string GermanTitle
- {
- get => this.returnTitleAsString(this.germanTitle);
- set => this.setTitleFromString(value, 2);
- }
-
- public string FrenchTitle
- {
- get => this.returnTitleAsString(this.frenchTitle);
- set => this.setTitleFromString(value, 3);
- }
-
- public string SpanishTitle
- {
- get => this.returnTitleAsString(this.spanishTitle);
- set => this.setTitleFromString(value, 4);
- }
-
- public string ItalianTitle
- {
- get => this.returnTitleAsString(this.italianTitle);
- set => this.setTitleFromString(value, 5);
- }
-
- public string DutchTitle
- {
- get => this.returnTitleAsString(this.dutchTitle);
- set => this.setTitleFromString(value, 6);
- }
-
- public string KoreanTitle
- {
- get => this.returnTitleAsString(this.koreanTitle);
- set => this.setTitleFromString(value, 7);
- }
-
- public string[] AllTitles => new string[8]
- {
- this.JapaneseTitle,
- this.EnglishTitle,
- this.GermanTitle,
- this.FrenchTitle,
- this.SpanishTitle,
- this.ItalianTitle,
- this.DutchTitle,
- this.KoreanTitle
- };
-
- public bool HashesMatch => this.hashesMatch;
-
- public static Headers.IMET Load(string pathToFile) => Headers.IMET.Load(File.ReadAllBytes(pathToFile));
-
- public static Headers.IMET Load(byte[] fileOrHeader)
- {
- Headers.HeaderType headerType = Headers.DetectHeader(fileOrHeader);
- switch (headerType)
+ ///
+ /// Convert HeaderType to int to get it's Length.
+ ///
+ public enum HeaderType
{
- case Headers.HeaderType.ShortIMET:
- case Headers.HeaderType.IMET:
- Headers.IMET imet = new Headers.IMET();
- if (headerType == Headers.HeaderType.ShortIMET)
- imet.isShortImet = true;
- MemoryStream memoryStream = new MemoryStream(fileOrHeader);
- try
+ None = 0,
+ ///
+ /// Used in banner.bin / icon.bin
+ ///
+ IMD5 = 32,
+ ///
+ /// Used in opening.bnr
+ ///
+ ShortIMET = 1536,
+ ///
+ /// Used in 00000000.app
+ ///
+ IMET = 1600,
+ }
+
+ #region Public Functions
+ ///
+ /// Checks a file for Headers.
+ ///
+ ///
+ ///
+ public static Headers.HeaderType DetectHeader(string pathToFile) => Headers.DetectHeader(File.ReadAllBytes(pathToFile));
+
+ ///
+ /// Checks the byte array for Headers.
+ ///
+ ///
+ ///
+ public static Headers.HeaderType DetectHeader(byte[] file)
+ {
+ if (file.Length > 68 && (int) Shared.Swap(BitConverter.ToUInt32(file, 64)) == (int) Headers.imetMagic)
+ return Headers.HeaderType.ShortIMET;
+ if (file.Length > 132 && (int) Shared.Swap(BitConverter.ToUInt32(file, 128)) == (int) Headers.imetMagic)
+ return Headers.HeaderType.IMET;
+ return file.Length > 4 && (int) Shared.Swap(BitConverter.ToUInt32(file, 0)) == (int) Headers.imd5Magic ? Headers.HeaderType.IMD5 : Headers.HeaderType.None;
+ }
+
+ ///
+ /// Checks the stream for Headers.
+ ///
+ ///
+ ///
+ public static Headers.HeaderType DetectHeader(Stream file)
+ {
+ byte[] buffer = new byte[4];
+ if (file.Length > 68L)
{
- imet.parseHeader((Stream) memoryStream);
+ file.Seek(64L, SeekOrigin.Begin);
+ file.Read(buffer, 0, buffer.Length);
+ if ((int) Shared.Swap(BitConverter.ToUInt32(buffer, 0)) == (int) Headers.imetMagic)
+ return Headers.HeaderType.ShortIMET;
}
- catch
+ if (file.Length > 132L)
{
- memoryStream.Dispose();
- throw;
+ file.Seek(128L, SeekOrigin.Begin);
+ file.Read(buffer, 0, buffer.Length);
+ if ((int) Shared.Swap(BitConverter.ToUInt32(buffer, 0)) == (int) Headers.imetMagic)
+ return Headers.HeaderType.IMET;
}
- memoryStream.Dispose();
- return imet;
- default:
- throw new Exception("No IMET Header found!");
+ if (file.Length > 4L)
+ {
+ file.Seek(0L, SeekOrigin.Begin);
+ file.Read(buffer, 0, buffer.Length);
+ if ((int) Shared.Swap(BitConverter.ToUInt32(buffer, 0)) == (int) Headers.imd5Magic)
+ return Headers.HeaderType.IMD5;
+ }
+ return Headers.HeaderType.None;
}
- }
+ #endregion
- public static Headers.IMET Load(Stream fileOrHeader)
- {
- Headers.HeaderType headerType = Headers.DetectHeader(fileOrHeader);
- switch (headerType)
+ public class IMET
{
- case Headers.HeaderType.ShortIMET:
- case Headers.HeaderType.IMET:
- Headers.IMET imet = new Headers.IMET();
- if (headerType == Headers.HeaderType.ShortIMET)
- imet.isShortImet = true;
- imet.parseHeader(fileOrHeader);
- return imet;
- default:
- throw new Exception("No IMET Header found!");
+ private bool hashesMatch = true;
+ private bool isShortImet;
+ private byte[] additionalPadding = new byte[64];
+ private byte[] padding = new byte[64];
+ private uint imetMagic = 1229800788;
+ private uint sizeOfHeader = 1536;
+ private uint unknown = 3;
+ private uint iconSize;
+ private uint bannerSize;
+ private uint soundSize;
+ private uint flags;
+ private byte[] japaneseTitle = new byte[84];
+ private byte[] englishTitle = new byte[84];
+ private byte[] germanTitle = new byte[84];
+ private byte[] frenchTitle = new byte[84];
+ private byte[] spanishTitle = new byte[84];
+ private byte[] italianTitle = new byte[84];
+ private byte[] dutchTitle = new byte[84];
+ private byte[] unknownTitle1 = new byte[84];
+ private byte[] unknownTitle2 = new byte[84];
+ private byte[] koreanTitle = new byte[84];
+ private byte[] padding2 = new byte[588];
+ private byte[] hash = new byte[16];
+
+ ///
+ /// Short IMET has a padding of 64 bytes at the beginning while Long IMET has 128.
+ ///
+ public bool IsShortIMET
+ {
+ get => this.isShortImet;
+ set => this.isShortImet = value;
+ }
+
+ ///
+ /// The size of uncompressed icon.bin
+ ///
+ public uint IconSize
+ {
+ get => this.iconSize;
+ set => this.iconSize = value;
+ }
+
+ ///
+ /// The size of uncompressed banner.bin
+ ///
+ public uint BannerSize
+ {
+ get => this.bannerSize;
+ set => this.bannerSize = value;
+ }
+
+ ///
+ /// The size of uncompressed sound.bin
+ ///
+ public uint SoundSize
+ {
+ get => this.soundSize;
+ set => this.soundSize = value;
+ }
+
+ ///
+ /// The Japanese Title.
+ ///
+ public string JapaneseTitle
+ {
+ get => this.returnTitleAsString(this.japaneseTitle);
+ set => this.setTitleFromString(value, 0);
+ }
+
+ ///
+ /// The English Title.
+ ///
+ public string EnglishTitle
+ {
+ get => this.returnTitleAsString(this.englishTitle);
+ set => this.setTitleFromString(value, 1);
+ }
+
+ ///
+ /// The German Title.
+ ///
+ public string GermanTitle
+ {
+ get => this.returnTitleAsString(this.germanTitle);
+ set => this.setTitleFromString(value, 2);
+ }
+
+ ///
+ /// The French Title.
+ ///
+ public string FrenchTitle
+ {
+ get => this.returnTitleAsString(this.frenchTitle);
+ set => this.setTitleFromString(value, 3);
+ }
+
+ ///
+ /// The Spanish Title.
+ ///
+ public string SpanishTitle
+ {
+ get => this.returnTitleAsString(this.spanishTitle);
+ set => this.setTitleFromString(value, 4);
+ }
+
+ ///
+ /// The Italian Title.
+ ///
+ public string ItalianTitle
+ {
+ get => this.returnTitleAsString(this.italianTitle);
+ set => this.setTitleFromString(value, 5);
+ }
+
+ ///
+ /// The Dutch Title.
+ ///
+ public string DutchTitle
+ {
+ get => this.returnTitleAsString(this.dutchTitle);
+ set => this.setTitleFromString(value, 6);
+ }
+
+ ///
+ /// The Korean Title.
+ ///
+ public string KoreanTitle
+ {
+ get => this.returnTitleAsString(this.koreanTitle);
+ set => this.setTitleFromString(value, 7);
+ }
+
+ ///
+ /// All Titles as a string array.
+ ///
+ public string[] AllTitles => new string[8]
+ {
+ this.JapaneseTitle,
+ this.EnglishTitle,
+ this.GermanTitle,
+ this.FrenchTitle,
+ this.SpanishTitle,
+ this.ItalianTitle,
+ this.DutchTitle,
+ this.KoreanTitle
+ };
+
+ ///
+ /// When parsing an IMET header, this value will turn false if the hash stored in the header doesn't match the headers hash.
+ ///
+ public bool HashesMatch => this.hashesMatch;
+
+ #region Public Functions
+ ///
+ /// Loads the IMET Header of a file.
+ ///
+ ///
+ ///
+ public static Headers.IMET Load(string pathToFile) => Headers.IMET.Load(File.ReadAllBytes(pathToFile));
+
+ ///
+ /// Loads the IMET Header of a byte array.
+ ///
+ ///
+ ///
+ public static Headers.IMET Load(byte[] fileOrHeader)
+ {
+ Headers.HeaderType headerType = Headers.DetectHeader(fileOrHeader);
+ switch (headerType)
+ {
+ case Headers.HeaderType.ShortIMET:
+ case Headers.HeaderType.IMET:
+ Headers.IMET imet = new Headers.IMET();
+ if (headerType == Headers.HeaderType.ShortIMET)
+ imet.isShortImet = true;
+ MemoryStream memoryStream = new MemoryStream(fileOrHeader);
+ try
+ {
+ imet.parseHeader((Stream) memoryStream);
+ }
+ catch
+ {
+ memoryStream.Dispose();
+ throw;
+ }
+ memoryStream.Dispose();
+ return imet;
+ default:
+ throw new Exception("No IMET Header found!");
+ }
+ }
+
+ ///
+ /// Loads the IMET Header of a stream.
+ ///
+ ///
+ ///
+ public static Headers.IMET Load(Stream fileOrHeader)
+ {
+ Headers.HeaderType headerType = Headers.DetectHeader(fileOrHeader);
+ switch (headerType)
+ {
+ case Headers.HeaderType.ShortIMET:
+ case Headers.HeaderType.IMET:
+ Headers.IMET imet = new Headers.IMET();
+ if (headerType == Headers.HeaderType.ShortIMET)
+ imet.isShortImet = true;
+ imet.parseHeader(fileOrHeader);
+ return imet;
+ default:
+ throw new Exception("No IMET Header found!");
+ }
+ }
+
+ ///
+ /// Creates a new IMET Header.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static Headers.IMET Create(
+ bool isShortImet,
+ int iconSize,
+ int bannerSize,
+ int soundSize,
+ params string[] titles)
+ {
+ Headers.IMET imet = new Headers.IMET();
+ imet.isShortImet = isShortImet;
+ for (int titleIndex = 0; titleIndex < titles.Length; ++titleIndex)
+ imet.setTitleFromString(titles[titleIndex], titleIndex);
+ for (int length = titles.Length; length < 8; ++length)
+ imet.setTitleFromString(titles.Length > 1 ? titles[1] : titles[0], length);
+ imet.iconSize = (uint) iconSize;
+ imet.bannerSize = (uint) bannerSize;
+ imet.soundSize = (uint) soundSize;
+ return imet;
+ }
+
+ ///
+ /// Removes the IMET Header of a file.
+ ///
+ ///
+ public static void RemoveHeader(string pathToFile)
+ {
+ byte[] bytes = Headers.IMET.RemoveHeader(File.ReadAllBytes(pathToFile));
+ File.Delete(pathToFile);
+ File.WriteAllBytes(pathToFile, bytes);
+ }
+
+ ///
+ /// Removes the IMET Header of a byte array.
+ ///
+ ///
+ ///
+ public static byte[] RemoveHeader(byte[] file)
+ {
+ Headers.HeaderType headerType = Headers.DetectHeader(file);
+ switch (headerType)
+ {
+ case Headers.HeaderType.ShortIMET:
+ case Headers.HeaderType.IMET:
+ byte[] numArray = new byte[(int) (file.Length - headerType)];
+ Array.Copy((Array) file, (int) headerType, (Array) numArray, 0, numArray.Length);
+ return numArray;
+ default:
+ throw new Exception("No IMET Header found!");
+ }
+ }
+
+ ///
+ /// Sets all title to the given string.
+ ///
+ ///
+ public void SetAllTitles(string newTitle)
+ {
+ for (int titleIndex = 0; titleIndex < 10; ++titleIndex)
+ this.setTitleFromString(newTitle, titleIndex);
+ }
+
+ ///
+ /// Returns the Header as a memory stream.
+ ///
+ ///
+ public MemoryStream ToMemoryStream()
+ {
+ MemoryStream memoryStream = new MemoryStream();
+ try
+ {
+ this.writeToStream((Stream) memoryStream);
+ return memoryStream;
+ }
+ catch
+ {
+ memoryStream.Dispose();
+ throw;
+ }
+ }
+
+ ///
+ /// Returns the Header as a byte array.
+ ///
+ ///
+ public byte[] ToByteArray() => this.ToMemoryStream().ToArray();
+
+ ///
+ /// Writes the Header to the given stream.
+ ///
+ ///
+ public void Write(Stream writeStream) => this.writeToStream(writeStream);
+
+ ///
+ /// Changes the Titles.
+ ///
+ ///
+ public void ChangeTitles(params string[] newTitles)
+ {
+ for (int titleIndex = 0; titleIndex < newTitles.Length; ++titleIndex)
+ this.setTitleFromString(newTitles[titleIndex], titleIndex);
+ for (int length = newTitles.Length; length < 8; ++length)
+ this.setTitleFromString(newTitles.Length > 1 ? newTitles[1] : newTitles[0], length);
+ }
+
+ ///
+ /// Returns a string array with the Titles.
+ ///
+ ///
+ public string[] GetTitles() => new string[8]
+ {
+ this.JapaneseTitle,
+ this.EnglishTitle,
+ this.GermanTitle,
+ this.FrenchTitle,
+ this.SpanishTitle,
+ this.ItalianTitle,
+ this.DutchTitle,
+ this.KoreanTitle
+ };
+ #endregion
+
+ #region Private Functions
+ private void writeToStream(Stream writeStream)
+ {
+ writeStream.Seek(0L, SeekOrigin.Begin);
+ if (!this.isShortImet)
+ writeStream.Write(this.additionalPadding, 0, this.additionalPadding.Length);
+ writeStream.Write(this.padding, 0, this.padding.Length);
+ writeStream.Write(BitConverter.GetBytes(Shared.Swap(this.imetMagic)), 0, 4);
+ writeStream.Write(BitConverter.GetBytes(Shared.Swap(this.sizeOfHeader)), 0, 4);
+ writeStream.Write(BitConverter.GetBytes(Shared.Swap(this.unknown)), 0, 4);
+ writeStream.Write(BitConverter.GetBytes(Shared.Swap(this.iconSize)), 0, 4);
+ writeStream.Write(BitConverter.GetBytes(Shared.Swap(this.bannerSize)), 0, 4);
+ writeStream.Write(BitConverter.GetBytes(Shared.Swap(this.soundSize)), 0, 4);
+ writeStream.Write(BitConverter.GetBytes(Shared.Swap(this.flags)), 0, 4);
+ writeStream.Write(this.japaneseTitle, 0, this.japaneseTitle.Length);
+ writeStream.Write(this.englishTitle, 0, this.englishTitle.Length);
+ writeStream.Write(this.germanTitle, 0, this.germanTitle.Length);
+ writeStream.Write(this.frenchTitle, 0, this.frenchTitle.Length);
+ writeStream.Write(this.spanishTitle, 0, this.spanishTitle.Length);
+ writeStream.Write(this.italianTitle, 0, this.italianTitle.Length);
+ writeStream.Write(this.dutchTitle, 0, this.dutchTitle.Length);
+ writeStream.Write(this.unknownTitle1, 0, this.unknownTitle1.Length);
+ writeStream.Write(this.unknownTitle2, 0, this.unknownTitle2.Length);
+ writeStream.Write(this.koreanTitle, 0, this.koreanTitle.Length);
+ writeStream.Write(this.padding2, 0, this.padding2.Length);
+ int position = (int) writeStream.Position;
+ this.hash = new byte[16];
+ writeStream.Write(this.hash, 0, this.hash.Length);
+ byte[] numArray = new byte[writeStream.Position];
+ writeStream.Seek(0L, SeekOrigin.Begin);
+ writeStream.Read(numArray, 0, numArray.Length);
+ this.computeHash(numArray, !this.isShortImet ? 64 : 0);
+ writeStream.Seek((long) position, SeekOrigin.Begin);
+ writeStream.Write(this.hash, 0, this.hash.Length);
+ }
+
+ private void computeHash(byte[] headerBytes, int hashPos)
+ {
+ MD5 md5 = MD5.Create();
+ this.hash = md5.ComputeHash(headerBytes, hashPos, 1536);
+ md5.Clear();
+ }
+
+ private void parseHeader(Stream headerStream)
+ {
+ headerStream.Seek(0L, SeekOrigin.Begin);
+ byte[] buffer1 = new byte[4];
+ if (!this.isShortImet)
+ headerStream.Read(this.additionalPadding, 0, this.additionalPadding.Length);
+ headerStream.Read(this.padding, 0, this.padding.Length);
+ headerStream.Read(buffer1, 0, 4);
+ if ((int) Shared.Swap(BitConverter.ToUInt32(buffer1, 0)) != (int) this.imetMagic)
+ throw new Exception("Invalid Magic!");
+ headerStream.Read(buffer1, 0, 4);
+ if ((int) Shared.Swap(BitConverter.ToUInt32(buffer1, 0)) != (int) this.sizeOfHeader)
+ throw new Exception("Invalid Header Size!");
+ headerStream.Read(buffer1, 0, 4);
+ this.unknown = Shared.Swap(BitConverter.ToUInt32(buffer1, 0));
+ headerStream.Read(buffer1, 0, 4);
+ this.iconSize = Shared.Swap(BitConverter.ToUInt32(buffer1, 0));
+ headerStream.Read(buffer1, 0, 4);
+ this.bannerSize = Shared.Swap(BitConverter.ToUInt32(buffer1, 0));
+ headerStream.Read(buffer1, 0, 4);
+ this.soundSize = Shared.Swap(BitConverter.ToUInt32(buffer1, 0));
+ headerStream.Read(buffer1, 0, 4);
+ this.flags = Shared.Swap(BitConverter.ToUInt32(buffer1, 0));
+ headerStream.Read(this.japaneseTitle, 0, this.japaneseTitle.Length);
+ headerStream.Read(this.englishTitle, 0, this.englishTitle.Length);
+ headerStream.Read(this.germanTitle, 0, this.germanTitle.Length);
+ headerStream.Read(this.frenchTitle, 0, this.frenchTitle.Length);
+ headerStream.Read(this.spanishTitle, 0, this.spanishTitle.Length);
+ headerStream.Read(this.italianTitle, 0, this.italianTitle.Length);
+ headerStream.Read(this.dutchTitle, 0, this.dutchTitle.Length);
+ headerStream.Read(this.unknownTitle1, 0, this.unknownTitle1.Length);
+ headerStream.Read(this.unknownTitle2, 0, this.unknownTitle2.Length);
+ headerStream.Read(this.koreanTitle, 0, this.koreanTitle.Length);
+ headerStream.Read(this.padding2, 0, this.padding2.Length);
+ headerStream.Read(this.hash, 0, this.hash.Length);
+ headerStream.Seek(-16L, SeekOrigin.Current);
+ headerStream.Write(new byte[16], 0, 16);
+ byte[] buffer2 = new byte[headerStream.Length];
+ headerStream.Seek(0L, SeekOrigin.Begin);
+ headerStream.Read(buffer2, 0, buffer2.Length);
+ MD5 md5 = MD5.Create();
+ byte[] hash = md5.ComputeHash(buffer2, !this.isShortImet ? 64 : 0, 1536);
+ md5.Clear();
+ this.hashesMatch = Shared.CompareByteArrays(hash, this.hash);
+ }
+
+ private string returnTitleAsString(byte[] title)
+ {
+ string empty = string.Empty;
+ for (int index = 0; index < 84; index += 2)
+ {
+ char ch = BitConverter.ToChar(new byte[2]
+ {
+ title[index + 1],
+ title[index]
+ }, 0);
+ if (ch != char.MinValue)
+ empty += ch.ToString();
+ }
+ return empty;
+ }
+
+ private void setTitleFromString(string title, int titleIndex)
+ {
+ byte[] numArray = new byte[84];
+ for (int index = 0; index < title.Length; ++index)
+ {
+ byte[] bytes = BitConverter.GetBytes(title[index]);
+ numArray[index * 2 + 1] = bytes[0];
+ numArray[index * 2] = bytes[1];
+ }
+ switch (titleIndex)
+ {
+ case 0:
+ this.japaneseTitle = numArray;
+ break;
+ case 1:
+ this.englishTitle = numArray;
+ break;
+ case 2:
+ this.germanTitle = numArray;
+ break;
+ case 3:
+ this.frenchTitle = numArray;
+ break;
+ case 4:
+ this.spanishTitle = numArray;
+ break;
+ case 5:
+ this.italianTitle = numArray;
+ break;
+ case 6:
+ this.dutchTitle = numArray;
+ break;
+ case 7:
+ this.koreanTitle = numArray;
+ break;
+ }
+ }
+ #endregion
}
- }
- public static Headers.IMET Create(
- bool isShortImet,
- int iconSize,
- int bannerSize,
- int soundSize,
- params string[] titles)
- {
- Headers.IMET imet = new Headers.IMET();
- imet.isShortImet = isShortImet;
- for (int titleIndex = 0; titleIndex < titles.Length; ++titleIndex)
- imet.setTitleFromString(titles[titleIndex], titleIndex);
- for (int length = titles.Length; length < 8; ++length)
- imet.setTitleFromString(titles.Length > 1 ? titles[1] : titles[0], length);
- imet.iconSize = (uint) iconSize;
- imet.bannerSize = (uint) bannerSize;
- imet.soundSize = (uint) soundSize;
- return imet;
- }
-
- public static void RemoveHeader(string pathToFile)
- {
- byte[] bytes = Headers.IMET.RemoveHeader(File.ReadAllBytes(pathToFile));
- File.Delete(pathToFile);
- File.WriteAllBytes(pathToFile, bytes);
- }
-
- public static byte[] RemoveHeader(byte[] file)
- {
- Headers.HeaderType headerType = Headers.DetectHeader(file);
- switch (headerType)
+ public class IMD5
{
- case Headers.HeaderType.ShortIMET:
- case Headers.HeaderType.IMET:
- byte[] numArray = new byte[(int) (file.Length - headerType)];
- Array.Copy((Array) file, (int) headerType, (Array) numArray, 0, numArray.Length);
- return numArray;
- default:
- throw new Exception("No IMET Header found!");
- }
- }
+ private uint imd5Magic = 1229800501;
+ private uint fileSize;
+ private byte[] padding = new byte[8];
+ private byte[] hash = new byte[16];
- public void SetAllTitles(string newTitle)
- {
- for (int titleIndex = 0; titleIndex < 10; ++titleIndex)
- this.setTitleFromString(newTitle, titleIndex);
- }
+ ///
+ /// The size of the file without the IMD5 Header.
+ ///
+ public uint FileSize => this.fileSize;
- public MemoryStream ToMemoryStream()
- {
- MemoryStream memoryStream = new MemoryStream();
- try
+ ///
+ /// The hash of the file without the IMD5 Header.
+ ///
+ public byte[] Hash => this.hash;
+
+ private IMD5()
{
- this.writeToStream((Stream) memoryStream);
- return memoryStream;
}
- catch
- {
- memoryStream.Dispose();
- throw;
+
+ #region Public Functions
+ ///
+ /// Loads the IMD5 Header of a file.
+ ///
+ ///
+ ///
+ public static Headers.IMD5 Load(string pathToFile) => Headers.IMD5.Load(File.ReadAllBytes(pathToFile));
+
+ ///
+ /// Loads the IMD5 Header of a byte array.
+ ///
+ ///
+ ///
+ public static Headers.IMD5 Load(byte[] fileOrHeader)
+ {
+ if (Headers.DetectHeader(fileOrHeader) != Headers.HeaderType.IMD5)
+ throw new Exception("No IMD5 Header found!");
+ Headers.IMD5 imD5 = new Headers.IMD5();
+ MemoryStream memoryStream = new MemoryStream(fileOrHeader);
+ try
+ {
+ imD5.parseHeader((Stream) memoryStream);
+ }
+ catch
+ {
+ memoryStream.Dispose();
+ throw;
+ }
+ memoryStream.Dispose();
+ return imD5;
+ }
+
+ ///
+ /// Loads the IMD5 Header of a stream.
+ ///
+ ///
+ ///
+ public static Headers.IMD5 Load(Stream fileOrHeader)
+ {
+ if (Headers.DetectHeader(fileOrHeader) != Headers.HeaderType.IMD5)
+ throw new Exception("No IMD5 Header found!");
+ Headers.IMD5 imD5 = new Headers.IMD5();
+ imD5.parseHeader(fileOrHeader);
+ return imD5;
+ }
+
+ ///
+ /// Creates a new IMD5 Header.
+ ///
+ ///
+ ///
+ public static Headers.IMD5 Create(byte[] file)
+ {
+ Headers.IMD5 imD5 = new Headers.IMD5();
+ imD5.fileSize = (uint) file.Length;
+ imD5.computeHash(file);
+ return imD5;
+ }
+
+ ///
+ /// Adds an IMD5 Header to a file.
+ ///
+ ///
+ public static void AddHeader(string pathToFile)
+ {
+ byte[] buffer = Headers.IMD5.AddHeader(File.ReadAllBytes(pathToFile));
+ File.Delete(pathToFile);
+ using (FileStream fileStream = new FileStream(pathToFile, FileMode.Create))
+ fileStream.Write(buffer, 0, buffer.Length);
+ }
+
+ ///
+ /// Adds an IMD5 Header to a byte array.
+ ///
+ ///
+ ///
+ public static byte[] AddHeader(byte[] file)
+ {
+ Headers.IMD5 imD5 = Headers.IMD5.Create(file);
+ MemoryStream memoryStream1 = new MemoryStream();
+ MemoryStream memoryStream2 = memoryStream1;
+ imD5.writeToStream((Stream) memoryStream2);
+ memoryStream1.Write(file, 0, file.Length);
+ byte[] array = memoryStream1.ToArray();
+ memoryStream1.Dispose();
+ return array;
+ }
+
+ ///
+ /// Removes the IMD5 Header of a file.
+ ///
+ ///
+ public static void RemoveHeader(string pathToFile)
+ {
+ byte[] buffer = Headers.IMD5.RemoveHeader(File.ReadAllBytes(pathToFile));
+ File.Delete(pathToFile);
+ using (FileStream fileStream = new FileStream(pathToFile, FileMode.Create))
+ fileStream.Write(buffer, 0, buffer.Length);
+ }
+
+ ///
+ /// Removes the IMD5 Header of a byte array.
+ ///
+ ///
+ ///
+ public static byte[] RemoveHeader(byte[] file)
+ {
+ MemoryStream memoryStream = new MemoryStream();
+ memoryStream.Write(file, 32, file.Length - 32);
+ byte[] array = memoryStream.ToArray();
+ memoryStream.Dispose();
+ return array;
+ }
+
+ ///
+ /// Returns the IMD5 Header as a memory stream.
+ ///
+ ///
+ public MemoryStream ToMemoryStream()
+ {
+ MemoryStream memoryStream = new MemoryStream();
+ try
+ {
+ this.writeToStream((Stream) memoryStream);
+ return memoryStream;
+ }
+ catch
+ {
+ memoryStream.Dispose();
+ throw;
+ }
+ }
+
+ ///
+ /// Returns the IMD5 Header as a byte array.
+ ///
+ ///
+ public byte[] ToByteArray() => this.ToMemoryStream().ToArray();
+
+ ///
+ /// Writes the IMD5 Header to the given stream.
+ ///
+ ///
+ public void Write(Stream writeStream) => this.writeToStream(writeStream);
+ #endregion
+
+ #region Private Functions
+ private void writeToStream(Stream writeStream)
+ {
+ writeStream.Seek(0L, SeekOrigin.Begin);
+ writeStream.Write(BitConverter.GetBytes(Shared.Swap(this.imd5Magic)), 0, 4);
+ writeStream.Write(BitConverter.GetBytes(Shared.Swap(this.fileSize)), 0, 4);
+ writeStream.Write(this.padding, 0, this.padding.Length);
+ writeStream.Write(this.hash, 0, this.hash.Length);
+ }
+
+ private void computeHash(byte[] bytesToHash)
+ {
+ MD5 md5 = MD5.Create();
+ this.hash = md5.ComputeHash(bytesToHash);
+ md5.Clear();
+ }
+
+ private void parseHeader(Stream headerStream)
+ {
+ headerStream.Seek(0L, SeekOrigin.Begin);
+ byte[] buffer = new byte[4];
+ headerStream.Read(buffer, 0, 4);
+ if ((int) Shared.Swap(BitConverter.ToUInt32(buffer, 0)) != (int) this.imd5Magic)
+ throw new Exception("Invalid Magic!");
+ headerStream.Read(buffer, 0, 4);
+ this.fileSize = Shared.Swap(BitConverter.ToUInt32(buffer, 0));
+ headerStream.Read(this.padding, 0, this.padding.Length);
+ headerStream.Read(this.hash, 0, this.hash.Length);
+ }
+ #endregion
}
- }
-
- public byte[] ToByteArray() => this.ToMemoryStream().ToArray();
-
- public void Write(Stream writeStream) => this.writeToStream(writeStream);
-
- public void ChangeTitles(params string[] newTitles)
- {
- for (int titleIndex = 0; titleIndex < newTitles.Length; ++titleIndex)
- this.setTitleFromString(newTitles[titleIndex], titleIndex);
- for (int length = newTitles.Length; length < 8; ++length)
- this.setTitleFromString(newTitles.Length > 1 ? newTitles[1] : newTitles[0], length);
- }
-
- public string[] GetTitles() => new string[8]
- {
- this.JapaneseTitle,
- this.EnglishTitle,
- this.GermanTitle,
- this.FrenchTitle,
- this.SpanishTitle,
- this.ItalianTitle,
- this.DutchTitle,
- this.KoreanTitle
- };
-
- private void writeToStream(Stream writeStream)
- {
- writeStream.Seek(0L, SeekOrigin.Begin);
- if (!this.isShortImet)
- writeStream.Write(this.additionalPadding, 0, this.additionalPadding.Length);
- writeStream.Write(this.padding, 0, this.padding.Length);
- writeStream.Write(BitConverter.GetBytes(Shared.Swap(this.imetMagic)), 0, 4);
- writeStream.Write(BitConverter.GetBytes(Shared.Swap(this.sizeOfHeader)), 0, 4);
- writeStream.Write(BitConverter.GetBytes(Shared.Swap(this.unknown)), 0, 4);
- writeStream.Write(BitConverter.GetBytes(Shared.Swap(this.iconSize)), 0, 4);
- writeStream.Write(BitConverter.GetBytes(Shared.Swap(this.bannerSize)), 0, 4);
- writeStream.Write(BitConverter.GetBytes(Shared.Swap(this.soundSize)), 0, 4);
- writeStream.Write(BitConverter.GetBytes(Shared.Swap(this.flags)), 0, 4);
- writeStream.Write(this.japaneseTitle, 0, this.japaneseTitle.Length);
- writeStream.Write(this.englishTitle, 0, this.englishTitle.Length);
- writeStream.Write(this.germanTitle, 0, this.germanTitle.Length);
- writeStream.Write(this.frenchTitle, 0, this.frenchTitle.Length);
- writeStream.Write(this.spanishTitle, 0, this.spanishTitle.Length);
- writeStream.Write(this.italianTitle, 0, this.italianTitle.Length);
- writeStream.Write(this.dutchTitle, 0, this.dutchTitle.Length);
- writeStream.Write(this.unknownTitle1, 0, this.unknownTitle1.Length);
- writeStream.Write(this.unknownTitle2, 0, this.unknownTitle2.Length);
- writeStream.Write(this.koreanTitle, 0, this.koreanTitle.Length);
- writeStream.Write(this.padding2, 0, this.padding2.Length);
- int position = (int) writeStream.Position;
- this.hash = new byte[16];
- writeStream.Write(this.hash, 0, this.hash.Length);
- byte[] numArray = new byte[writeStream.Position];
- writeStream.Seek(0L, SeekOrigin.Begin);
- writeStream.Read(numArray, 0, numArray.Length);
- this.computeHash(numArray, !this.isShortImet ? 64 : 0);
- writeStream.Seek((long) position, SeekOrigin.Begin);
- writeStream.Write(this.hash, 0, this.hash.Length);
- }
-
- private void computeHash(byte[] headerBytes, int hashPos)
- {
- MD5 md5 = MD5.Create();
- this.hash = md5.ComputeHash(headerBytes, hashPos, 1536);
- md5.Clear();
- }
-
- private void parseHeader(Stream headerStream)
- {
- headerStream.Seek(0L, SeekOrigin.Begin);
- byte[] buffer1 = new byte[4];
- if (!this.isShortImet)
- headerStream.Read(this.additionalPadding, 0, this.additionalPadding.Length);
- headerStream.Read(this.padding, 0, this.padding.Length);
- headerStream.Read(buffer1, 0, 4);
- if ((int) Shared.Swap(BitConverter.ToUInt32(buffer1, 0)) != (int) this.imetMagic)
- throw new Exception("Invalid Magic!");
- headerStream.Read(buffer1, 0, 4);
- if ((int) Shared.Swap(BitConverter.ToUInt32(buffer1, 0)) != (int) this.sizeOfHeader)
- throw new Exception("Invalid Header Size!");
- headerStream.Read(buffer1, 0, 4);
- this.unknown = Shared.Swap(BitConverter.ToUInt32(buffer1, 0));
- headerStream.Read(buffer1, 0, 4);
- this.iconSize = Shared.Swap(BitConverter.ToUInt32(buffer1, 0));
- headerStream.Read(buffer1, 0, 4);
- this.bannerSize = Shared.Swap(BitConverter.ToUInt32(buffer1, 0));
- headerStream.Read(buffer1, 0, 4);
- this.soundSize = Shared.Swap(BitConverter.ToUInt32(buffer1, 0));
- headerStream.Read(buffer1, 0, 4);
- this.flags = Shared.Swap(BitConverter.ToUInt32(buffer1, 0));
- headerStream.Read(this.japaneseTitle, 0, this.japaneseTitle.Length);
- headerStream.Read(this.englishTitle, 0, this.englishTitle.Length);
- headerStream.Read(this.germanTitle, 0, this.germanTitle.Length);
- headerStream.Read(this.frenchTitle, 0, this.frenchTitle.Length);
- headerStream.Read(this.spanishTitle, 0, this.spanishTitle.Length);
- headerStream.Read(this.italianTitle, 0, this.italianTitle.Length);
- headerStream.Read(this.dutchTitle, 0, this.dutchTitle.Length);
- headerStream.Read(this.unknownTitle1, 0, this.unknownTitle1.Length);
- headerStream.Read(this.unknownTitle2, 0, this.unknownTitle2.Length);
- headerStream.Read(this.koreanTitle, 0, this.koreanTitle.Length);
- headerStream.Read(this.padding2, 0, this.padding2.Length);
- headerStream.Read(this.hash, 0, this.hash.Length);
- headerStream.Seek(-16L, SeekOrigin.Current);
- headerStream.Write(new byte[16], 0, 16);
- byte[] buffer2 = new byte[headerStream.Length];
- headerStream.Seek(0L, SeekOrigin.Begin);
- headerStream.Read(buffer2, 0, buffer2.Length);
- MD5 md5 = MD5.Create();
- byte[] hash = md5.ComputeHash(buffer2, !this.isShortImet ? 64 : 0, 1536);
- md5.Clear();
- this.hashesMatch = Shared.CompareByteArrays(hash, this.hash);
- }
-
- private string returnTitleAsString(byte[] title)
- {
- string empty = string.Empty;
- for (int index = 0; index < 84; index += 2)
- {
- char ch = BitConverter.ToChar(new byte[2]
- {
- title[index + 1],
- title[index]
- }, 0);
- if (ch != char.MinValue)
- empty += ch.ToString();
- }
- return empty;
- }
-
- private void setTitleFromString(string title, int titleIndex)
- {
- byte[] numArray = new byte[84];
- for (int index = 0; index < title.Length; ++index)
- {
- byte[] bytes = BitConverter.GetBytes(title[index]);
- numArray[index * 2 + 1] = bytes[0];
- numArray[index * 2] = bytes[1];
- }
- switch (titleIndex)
- {
- case 0:
- this.japaneseTitle = numArray;
- break;
- case 1:
- this.englishTitle = numArray;
- break;
- case 2:
- this.germanTitle = numArray;
- break;
- case 3:
- this.frenchTitle = numArray;
- break;
- case 4:
- this.spanishTitle = numArray;
- break;
- case 5:
- this.italianTitle = numArray;
- break;
- case 6:
- this.dutchTitle = numArray;
- break;
- case 7:
- this.koreanTitle = numArray;
- break;
- }
- }
}
-
- public class IMD5
- {
- private uint imd5Magic = 1229800501;
- private uint fileSize;
- private byte[] padding = new byte[8];
- private byte[] hash = new byte[16];
-
- public uint FileSize => this.fileSize;
-
- public byte[] Hash => this.hash;
-
- private IMD5()
- {
- }
-
- public static Headers.IMD5 Load(string pathToFile) => Headers.IMD5.Load(File.ReadAllBytes(pathToFile));
-
- public static Headers.IMD5 Load(byte[] fileOrHeader)
- {
- if (Headers.DetectHeader(fileOrHeader) != Headers.HeaderType.IMD5)
- throw new Exception("No IMD5 Header found!");
- Headers.IMD5 imD5 = new Headers.IMD5();
- MemoryStream memoryStream = new MemoryStream(fileOrHeader);
- try
- {
- imD5.parseHeader((Stream) memoryStream);
- }
- catch
- {
- memoryStream.Dispose();
- throw;
- }
- memoryStream.Dispose();
- return imD5;
- }
-
- public static Headers.IMD5 Load(Stream fileOrHeader)
- {
- if (Headers.DetectHeader(fileOrHeader) != Headers.HeaderType.IMD5)
- throw new Exception("No IMD5 Header found!");
- Headers.IMD5 imD5 = new Headers.IMD5();
- imD5.parseHeader(fileOrHeader);
- return imD5;
- }
-
- public static Headers.IMD5 Create(byte[] file)
- {
- Headers.IMD5 imD5 = new Headers.IMD5();
- imD5.fileSize = (uint) file.Length;
- imD5.computeHash(file);
- return imD5;
- }
-
- public static void AddHeader(string pathToFile)
- {
- byte[] buffer = Headers.IMD5.AddHeader(File.ReadAllBytes(pathToFile));
- File.Delete(pathToFile);
- using (FileStream fileStream = new FileStream(pathToFile, FileMode.Create))
- fileStream.Write(buffer, 0, buffer.Length);
- }
-
- public static byte[] AddHeader(byte[] file)
- {
- Headers.IMD5 imD5 = Headers.IMD5.Create(file);
- MemoryStream memoryStream1 = new MemoryStream();
- MemoryStream memoryStream2 = memoryStream1;
- imD5.writeToStream((Stream) memoryStream2);
- memoryStream1.Write(file, 0, file.Length);
- byte[] array = memoryStream1.ToArray();
- memoryStream1.Dispose();
- return array;
- }
-
- public static void RemoveHeader(string pathToFile)
- {
- byte[] buffer = Headers.IMD5.RemoveHeader(File.ReadAllBytes(pathToFile));
- File.Delete(pathToFile);
- using (FileStream fileStream = new FileStream(pathToFile, FileMode.Create))
- fileStream.Write(buffer, 0, buffer.Length);
- }
-
- public static byte[] RemoveHeader(byte[] file)
- {
- MemoryStream memoryStream = new MemoryStream();
- memoryStream.Write(file, 32, file.Length - 32);
- byte[] array = memoryStream.ToArray();
- memoryStream.Dispose();
- return array;
- }
-
- public MemoryStream ToMemoryStream()
- {
- MemoryStream memoryStream = new MemoryStream();
- try
- {
- this.writeToStream((Stream) memoryStream);
- return memoryStream;
- }
- catch
- {
- memoryStream.Dispose();
- throw;
- }
- }
-
- public byte[] ToByteArray() => this.ToMemoryStream().ToArray();
-
- public void Write(Stream writeStream) => this.writeToStream(writeStream);
-
- private void writeToStream(Stream writeStream)
- {
- writeStream.Seek(0L, SeekOrigin.Begin);
- writeStream.Write(BitConverter.GetBytes(Shared.Swap(this.imd5Magic)), 0, 4);
- writeStream.Write(BitConverter.GetBytes(Shared.Swap(this.fileSize)), 0, 4);
- writeStream.Write(this.padding, 0, this.padding.Length);
- writeStream.Write(this.hash, 0, this.hash.Length);
- }
-
- private void computeHash(byte[] bytesToHash)
- {
- MD5 md5 = MD5.Create();
- this.hash = md5.ComputeHash(bytesToHash);
- md5.Clear();
- }
-
- private void parseHeader(Stream headerStream)
- {
- headerStream.Seek(0L, SeekOrigin.Begin);
- byte[] buffer = new byte[4];
- headerStream.Read(buffer, 0, 4);
- if ((int) Shared.Swap(BitConverter.ToUInt32(buffer, 0)) != (int) this.imd5Magic)
- throw new Exception("Invalid Magic!");
- headerStream.Read(buffer, 0, 4);
- this.fileSize = Shared.Swap(BitConverter.ToUInt32(buffer, 0));
- headerStream.Read(this.padding, 0, this.padding.Length);
- headerStream.Read(this.hash, 0, this.hash.Length);
- }
- }
- }
}
diff --git a/HexView.cs b/HexView.cs
index 232cbb1..864765d 100644
--- a/HexView.cs
+++ b/HexView.cs
@@ -1,8 +1,20 @@
-// Decompiled with JetBrains decompiler
-// Type: libWiiSharp.HexView
-// Assembly: libWiiSharp, Version=0.4.0.0, Culture=neutral, PublicKeyToken=null
-// MVID: FBF36F3D-B5D6-481F-B5F5-1BD3C19E13B2
-// Assembly location: C:\Users\theso\Downloads\NCPatcher\pack\libWiiSharp.dll
+/* This file is part of libWiiSharp
+ * Copyright (C) 2009 Leathl
+ * Copyright (C) 2020 Github Contributors
+ *
+ * libWiiSharp 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.
+ *
+ * libWiiSharp 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.Collections.Generic;
@@ -12,249 +24,319 @@ using System.Windows.Forms;
namespace libWiiSharp
{
- public static class HexView
- {
- private static string savedValue;
-
- public static void DumpToListView(byte[] data, ListView listView) => HexView.dumpToListView(data, listView);
-
- public static void DumpToDataGridView(byte[] data, DataGridView dataGridView) => HexView.dumpToDataGridView(data, dataGridView);
-
- public static byte[] DumpFromDataGridView(DataGridView dataGridView) => HexView.dumpFromDataGridView(dataGridView);
-
- public static void DumpToRichTextBox(byte[] data, RichTextBox richTextBox)
+ ///
+ /// A static class that provides functions to dump a byte array to view it like in a hex-editor.
+ /// In combination with a DataGridView, it's even able to act like a hex-editor.
+ /// Big files (25kB ++) will take quite a long time, so don't use this for big files.
+ ///
+ public static class HexView
{
- richTextBox.Clear();
- richTextBox.Font = new Font("Courier New", 9f);
- richTextBox.ReadOnly = true;
- richTextBox.Text = HexView.DumpAsString(data);
+ private static string savedValue;
+
+ #region Public Functions
+ ///
+ /// Displays the byte array like a hex editor in a ListView.
+ /// Columns will be created, estimated width is ~685 px.
+ /// Big files (25kB ++) will take quite a long time, so don't use this for big files.
+ ///
+ ///
+ ///
+ public static void DumpToListView(byte[] data, ListView listView) => HexView.dumpToListView(data, listView);
+
+ ///
+ /// Displays the byte array like a hex editor in a DataGridView.
+ /// Columns will be created, estimated width is ~685 px.
+ /// Big files (25kB ++) will take quite a long time, so don't use this for big files.
+ ///
+ ///
+ ///
+ public static void DumpToDataGridView(byte[] data, DataGridView dataGridView) => HexView.dumpToDataGridView(data, dataGridView);
+
+ ///
+ /// Dumps a DataGridView back to a byte array.
+ /// The DataGridView must have the right format.
+ /// Big files (25kB ++) will take quite a long time, so don't use this for big files.
+ ///
+ ///
+ ///
+ public static byte[] DumpFromDataGridView(DataGridView dataGridView) => HexView.dumpFromDataGridView(dataGridView);
+
+ ///
+ /// Displays the byte array like a hex editor in a RichTextBox.
+ /// Big files (25kB ++) will take quite a long time, so don't use this for big files.
+ ///
+ ///
+ ///
+ public static void DumpToRichTextBox(byte[] data, RichTextBox richTextBox)
+ {
+ richTextBox.Clear();
+ richTextBox.Font = new Font("Courier New", 9f);
+ richTextBox.ReadOnly = true;
+ richTextBox.Text = HexView.DumpAsString(data);
+ }
+
+ ///
+ /// Displays the byte array like a hex editor in a TextBox.
+ /// Big files (25kB ++) will take quite a long time, so don't use this for big files.
+ ///
+ ///
+ ///
+ public static void DumpToTextBox(byte[] data, TextBox textBox)
+ {
+ textBox.Multiline = true;
+ textBox.Font = new Font("Courier New", 9f);
+ textBox.ReadOnly = true;
+ textBox.Text = HexView.DumpAsString(data).Replace("\n", "\r\n");
+ }
+
+ ///
+ /// Displays the byte array like a hex editor as a string array.
+ /// Be sure to use "Courier New" as a font, so every char has the same width.
+ /// Big files (25kB ++) will take quite a long time, so don't use this for big files.
+ ///
+ ///
+ ///
+ public static string[] DumpAsStringArray(byte[] data) => HexView.dumpAsStringArray(data);
+
+ ///
+ /// Displays the byte array like a hex editor as a string.
+ /// Be sure to use "Courier New" as a font, so every char has the same width.
+ /// Big files (25kB ++) will take quite a long time, so don't use this for big files.
+ ///
+ ///
+ ///
+ public static string DumpAsString(byte[] data) => string.Join("\n", HexView.dumpAsStringArray(data));
+
+ ///
+ /// Link your DataGridView's CellEndEdit event with this function.
+ /// The dump and byte values will be synchronized.
+ /// Don't forget to also link the CellBeginEdit event.
+ ///
+ ///
+ ///
+ public static void DataGridView_CellEndEdit(object sender, DataGridViewCellEventArgs e)
+ {
+ try
+ {
+ DataGridView dataGridView = sender as DataGridView;
+ if (dataGridView.Columns[e.ColumnIndex].HeaderText.ToLower() == "dump")
+ {
+ string str = (string) dataGridView.Rows[e.RowIndex].Cells[17].Value;
+ if (!(str != HexView.savedValue))
+ return;
+ if (str.Length != 16)
+ throw new Exception();
+ for (int index = 0; index < 16; ++index)
+ {
+ if ((int) HexView.toAscii(byte.Parse((string) dataGridView.Rows[e.RowIndex].Cells[index + 1].Value, NumberStyles.HexNumber)) != (int) str[index])
+ dataGridView.Rows[e.RowIndex].Cells[index + 1].Value = (object) HexView.fromAscii(str[index]).ToString("x2");
+ }
+ }
+ else
+ {
+ if (((string) dataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].Value).Length == 1)
+ dataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = (object) ("0" + dataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].Value?.ToString());
+ int startIndex = int.Parse(dataGridView.Columns[e.ColumnIndex].HeaderText, NumberStyles.HexNumber);
+ string str = ((string) dataGridView.Rows[e.RowIndex].Cells[17].Value).Remove(startIndex, 1).Insert(startIndex, HexView.toAscii(byte.Parse((string) dataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].Value, NumberStyles.HexNumber)).ToString());
+ dataGridView.Rows[e.RowIndex].Cells[17].Value = (object) str;
+ if (((string) dataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].Value).Length <= 2)
+ return;
+ dataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = (object) ((string) dataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].Value).Remove(0, ((string) dataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].Value).Length - 2);
+ }
+ }
+ catch
+ {
+ ((DataGridView) sender).Rows[e.RowIndex].Cells[e.ColumnIndex].Value = (object) HexView.savedValue;
+ }
+ }
+
+ ///
+ /// Link your DataGridView's CellBeginEdit event with this function.
+ /// The dump and byte values will be synchronized.
+ /// Don't forget to also link the CellEndEdit event.
+ ///
+ ///
+ ///
+ public static void DataGridView_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e) => HexView.savedValue = (string) ((DataGridView) sender).Rows[e.RowIndex].Cells[e.ColumnIndex].Value;
+ #endregion
+
+ #region Private Functions
+ private static string[] dumpAsStringArray(byte[] data)
+ {
+ List stringList = new List();
+ string empty = string.Empty;
+ int num;
+ char ascii;
+ for (num = 0; (double) (data.Length - num) / 16.0 >= 1.0; num += 16)
+ {
+ string str1 = string.Empty + num.ToString("x8") + " ";
+ string str2 = string.Empty;
+ for (int index = 0; index < 16; ++index)
+ {
+ str1 = str1 + data[num + index].ToString("x2") + " ";
+ string str3 = str2;
+ ascii = HexView.toAscii(data[num + index]);
+ string str4 = ascii.ToString();
+ str2 = str3 + str4;
+ }
+ string str5 = str1 + " " + str2;
+ stringList.Add(str5);
+ }
+ if (data.Length > num)
+ {
+ string str1 = string.Empty + num.ToString("x8") + " ";
+ string str2 = string.Empty;
+ for (int index = 0; index < 16; ++index)
+ {
+ if (index < data.Length - num)
+ {
+ str1 = str1 + data[num + index].ToString("x2") + " ";
+ string str3 = str2;
+ ascii = HexView.toAscii(data[num + index]);
+ string str4 = ascii.ToString();
+ str2 = str3 + str4;
+ }
+ else
+ str1 += " ";
+ }
+ string str5 = str1 + " " + str2;
+ stringList.Add(str5);
+ }
+ return stringList.ToArray();
+ }
+
+ private static byte[] dumpFromDataGridView(DataGridView dataGridView)
+ {
+ try
+ {
+ List byteList = new List();
+ for (int index1 = 0; !string.IsNullOrEmpty((string) dataGridView.Rows[index1].Cells[1].Value); ++index1)
+ {
+ for (int index2 = 0; index2 < 16; ++index2)
+ {
+ if (!string.IsNullOrEmpty((string) dataGridView.Rows[index1].Cells[index2 + 1].Value))
+ byteList.Add(byte.Parse((string) dataGridView.Rows[index1].Cells[index2 + 1].Value, NumberStyles.HexNumber));
+ }
+ if (index1 == dataGridView.Rows.Count - 1)
+ break;
+ }
+ return byteList.ToArray();
+ }
+ catch
+ {
+ throw new Exception("An error occured. The DataGridView might have the wrong format!");
+ }
+ }
+
+ private static void dumpToDataGridView(byte[] data, DataGridView dataGridView)
+ {
+ dataGridView.Columns.Clear();
+ dataGridView.Rows.Clear();
+ dataGridView.Font = new Font("Courier New", 9f);
+ dataGridView.Columns.Add(new DataGridViewColumn()
+ {
+ HeaderText = "Offset",
+ Width = 80,
+ CellTemplate = (DataGridViewCell) new DataGridViewTextBoxCell()
+ });
+ for (int index = 0; index < 16; ++index)
+ dataGridView.Columns.Add(new DataGridViewColumn()
+ {
+ HeaderText = index.ToString("x1"),
+ Width = 30,
+ CellTemplate = (DataGridViewCell) new DataGridViewTextBoxCell()
+ });
+ dataGridView.Columns.Add(new DataGridViewColumn()
+ {
+ HeaderText = "Dump",
+ Width = 125,
+ CellTemplate = (DataGridViewCell) new DataGridViewTextBoxCell()
+ });
+ int num;
+ for (num = 0; (double) (data.Length - num) / 16.0 >= 1.0; num += 16)
+ {
+ DataGridViewRow dataGridViewRow = new DataGridViewRow();
+ int index1 = dataGridViewRow.Cells.Add((DataGridViewCell) new DataGridViewTextBoxCell());
+ dataGridViewRow.Cells[index1].Value = (object) num.ToString("x8");
+ dataGridViewRow.Cells[index1].ReadOnly = true;
+ string empty = string.Empty;
+ for (int index2 = 0; index2 < 16; ++index2)
+ {
+ int index3 = dataGridViewRow.Cells.Add((DataGridViewCell) new DataGridViewTextBoxCell());
+ dataGridViewRow.Cells[index3].Value = (object) data[num + index2].ToString("x2");
+ empty += HexView.toAscii(data[num + index2]).ToString();
+ }
+ int index4 = dataGridViewRow.Cells.Add((DataGridViewCell) new DataGridViewTextBoxCell());
+ dataGridViewRow.Cells[index4].Value = (object) empty;
+ dataGridView.Rows.Add(dataGridViewRow);
+ }
+ if (data.Length <= num)
+ return;
+ DataGridViewRow dataGridViewRow1 = new DataGridViewRow();
+ int index5 = dataGridViewRow1.Cells.Add((DataGridViewCell) new DataGridViewTextBoxCell());
+ dataGridViewRow1.Cells[index5].Value = (object) num.ToString("x8");
+ dataGridViewRow1.Cells[index5].ReadOnly = true;
+ string empty1 = string.Empty;
+ for (int index1 = 0; index1 < 16; ++index1)
+ {
+ if (index1 < data.Length - num)
+ {
+ int index2 = dataGridViewRow1.Cells.Add((DataGridViewCell) new DataGridViewTextBoxCell());
+ dataGridViewRow1.Cells[index2].Value = (object) data[num + index1].ToString("x2");
+ empty1 += HexView.toAscii(data[num + index1]).ToString();
+ }
+ else
+ dataGridViewRow1.Cells.Add((DataGridViewCell) new DataGridViewTextBoxCell());
+ }
+ int index6 = dataGridViewRow1.Cells.Add((DataGridViewCell) new DataGridViewTextBoxCell());
+ dataGridViewRow1.Cells[index6].Value = (object) empty1;
+ dataGridView.Rows.Add(dataGridViewRow1);
+ }
+
+ private static void dumpToListView(byte[] data, ListView listView)
+ {
+ listView.Columns.Clear();
+ listView.Items.Clear();
+ listView.View = View.Details;
+ listView.Font = new Font("Courier New", 9f);
+ listView.Columns.Add("Offset", "Offset", 80, HorizontalAlignment.Left, string.Empty);
+ for (int index = 0; index < 16; ++index)
+ listView.Columns.Add(index.ToString("x1"), index.ToString("x1"), 30, HorizontalAlignment.Left, string.Empty);
+ listView.Columns.Add("Dump", "Dump", 125, HorizontalAlignment.Left, string.Empty);
+ int num;
+ for (num = 0; (double) (data.Length - num) / 16.0 >= 1.0; num += 16)
+ {
+ ListViewItem listViewItem = new ListViewItem(num.ToString("x8"));
+ string empty = string.Empty;
+ for (int index = 0; index < 16; ++index)
+ {
+ listViewItem.SubItems.Add(data[num + index].ToString("x2"));
+ empty += HexView.toAscii(data[num + index]).ToString();
+ }
+ listViewItem.SubItems.Add(empty);
+ listView.Items.Add(listViewItem);
+ }
+ if (data.Length <= num)
+ return;
+ ListViewItem listViewItem1 = new ListViewItem(num.ToString("x8"));
+ string empty1 = string.Empty;
+ for (int index = 0; index < 16; ++index)
+ {
+ if (index < data.Length - num)
+ {
+ listViewItem1.SubItems.Add(data[num + index].ToString("x2"));
+ empty1 += HexView.toAscii(data[num + index]).ToString();
+ }
+ else
+ listViewItem1.SubItems.Add(string.Empty);
+ }
+ listViewItem1.SubItems.Add(empty1);
+ listView.Items.Add(listViewItem1);
+ }
+
+ private static char toAscii(byte value) => value >= (byte) 32 && value <= (byte) 126 ? (char) value : '.';
+
+ private static byte fromAscii(char value) => (byte) value;
+ #endregion
}
-
- public static void DumpToTextBox(byte[] data, TextBox textBox)
- {
- textBox.Multiline = true;
- textBox.Font = new Font("Courier New", 9f);
- textBox.ReadOnly = true;
- textBox.Text = HexView.DumpAsString(data).Replace("\n", "\r\n");
- }
-
- public static string[] DumpAsStringArray(byte[] data) => HexView.dumpAsStringArray(data);
-
- public static string DumpAsString(byte[] data) => string.Join("\n", HexView.dumpAsStringArray(data));
-
- public static void DataGridView_CellEndEdit(object sender, DataGridViewCellEventArgs e)
- {
- try
- {
- DataGridView dataGridView = sender as DataGridView;
- if (dataGridView.Columns[e.ColumnIndex].HeaderText.ToLower() == "dump")
- {
- string str = (string) dataGridView.Rows[e.RowIndex].Cells[17].Value;
- if (!(str != HexView.savedValue))
- return;
- if (str.Length != 16)
- throw new Exception();
- for (int index = 0; index < 16; ++index)
- {
- if ((int) HexView.toAscii(byte.Parse((string) dataGridView.Rows[e.RowIndex].Cells[index + 1].Value, NumberStyles.HexNumber)) != (int) str[index])
- dataGridView.Rows[e.RowIndex].Cells[index + 1].Value = (object) HexView.fromAscii(str[index]).ToString("x2");
- }
- }
- else
- {
- if (((string) dataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].Value).Length == 1)
- dataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = (object) ("0" + dataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].Value?.ToString());
- int startIndex = int.Parse(dataGridView.Columns[e.ColumnIndex].HeaderText, NumberStyles.HexNumber);
- string str = ((string) dataGridView.Rows[e.RowIndex].Cells[17].Value).Remove(startIndex, 1).Insert(startIndex, HexView.toAscii(byte.Parse((string) dataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].Value, NumberStyles.HexNumber)).ToString());
- dataGridView.Rows[e.RowIndex].Cells[17].Value = (object) str;
- if (((string) dataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].Value).Length <= 2)
- return;
- dataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = (object) ((string) dataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].Value).Remove(0, ((string) dataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].Value).Length - 2);
- }
- }
- catch
- {
- ((DataGridView) sender).Rows[e.RowIndex].Cells[e.ColumnIndex].Value = (object) HexView.savedValue;
- }
- }
-
- public static void DataGridView_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e) => HexView.savedValue = (string) ((DataGridView) sender).Rows[e.RowIndex].Cells[e.ColumnIndex].Value;
-
- private static string[] dumpAsStringArray(byte[] data)
- {
- List stringList = new List();
- string empty = string.Empty;
- int num;
- char ascii;
- for (num = 0; (double) (data.Length - num) / 16.0 >= 1.0; num += 16)
- {
- string str1 = string.Empty + num.ToString("x8") + " ";
- string str2 = string.Empty;
- for (int index = 0; index < 16; ++index)
- {
- str1 = str1 + data[num + index].ToString("x2") + " ";
- string str3 = str2;
- ascii = HexView.toAscii(data[num + index]);
- string str4 = ascii.ToString();
- str2 = str3 + str4;
- }
- string str5 = str1 + " " + str2;
- stringList.Add(str5);
- }
- if (data.Length > num)
- {
- string str1 = string.Empty + num.ToString("x8") + " ";
- string str2 = string.Empty;
- for (int index = 0; index < 16; ++index)
- {
- if (index < data.Length - num)
- {
- str1 = str1 + data[num + index].ToString("x2") + " ";
- string str3 = str2;
- ascii = HexView.toAscii(data[num + index]);
- string str4 = ascii.ToString();
- str2 = str3 + str4;
- }
- else
- str1 += " ";
- }
- string str5 = str1 + " " + str2;
- stringList.Add(str5);
- }
- return stringList.ToArray();
- }
-
- private static byte[] dumpFromDataGridView(DataGridView dataGridView)
- {
- try
- {
- List byteList = new List();
- for (int index1 = 0; !string.IsNullOrEmpty((string) dataGridView.Rows[index1].Cells[1].Value); ++index1)
- {
- for (int index2 = 0; index2 < 16; ++index2)
- {
- if (!string.IsNullOrEmpty((string) dataGridView.Rows[index1].Cells[index2 + 1].Value))
- byteList.Add(byte.Parse((string) dataGridView.Rows[index1].Cells[index2 + 1].Value, NumberStyles.HexNumber));
- }
- if (index1 == dataGridView.Rows.Count - 1)
- break;
- }
- return byteList.ToArray();
- }
- catch
- {
- throw new Exception("An error occured. The DataGridView might have the wrong format!");
- }
- }
-
- private static void dumpToDataGridView(byte[] data, DataGridView dataGridView)
- {
- dataGridView.Columns.Clear();
- dataGridView.Rows.Clear();
- dataGridView.Font = new Font("Courier New", 9f);
- dataGridView.Columns.Add(new DataGridViewColumn()
- {
- HeaderText = "Offset",
- Width = 80,
- CellTemplate = (DataGridViewCell) new DataGridViewTextBoxCell()
- });
- for (int index = 0; index < 16; ++index)
- dataGridView.Columns.Add(new DataGridViewColumn()
- {
- HeaderText = index.ToString("x1"),
- Width = 30,
- CellTemplate = (DataGridViewCell) new DataGridViewTextBoxCell()
- });
- dataGridView.Columns.Add(new DataGridViewColumn()
- {
- HeaderText = "Dump",
- Width = 125,
- CellTemplate = (DataGridViewCell) new DataGridViewTextBoxCell()
- });
- int num;
- for (num = 0; (double) (data.Length - num) / 16.0 >= 1.0; num += 16)
- {
- DataGridViewRow dataGridViewRow = new DataGridViewRow();
- int index1 = dataGridViewRow.Cells.Add((DataGridViewCell) new DataGridViewTextBoxCell());
- dataGridViewRow.Cells[index1].Value = (object) num.ToString("x8");
- dataGridViewRow.Cells[index1].ReadOnly = true;
- string empty = string.Empty;
- for (int index2 = 0; index2 < 16; ++index2)
- {
- int index3 = dataGridViewRow.Cells.Add((DataGridViewCell) new DataGridViewTextBoxCell());
- dataGridViewRow.Cells[index3].Value = (object) data[num + index2].ToString("x2");
- empty += HexView.toAscii(data[num + index2]).ToString();
- }
- int index4 = dataGridViewRow.Cells.Add((DataGridViewCell) new DataGridViewTextBoxCell());
- dataGridViewRow.Cells[index4].Value = (object) empty;
- dataGridView.Rows.Add(dataGridViewRow);
- }
- if (data.Length <= num)
- return;
- DataGridViewRow dataGridViewRow1 = new DataGridViewRow();
- int index5 = dataGridViewRow1.Cells.Add((DataGridViewCell) new DataGridViewTextBoxCell());
- dataGridViewRow1.Cells[index5].Value = (object) num.ToString("x8");
- dataGridViewRow1.Cells[index5].ReadOnly = true;
- string empty1 = string.Empty;
- for (int index1 = 0; index1 < 16; ++index1)
- {
- if (index1 < data.Length - num)
- {
- int index2 = dataGridViewRow1.Cells.Add((DataGridViewCell) new DataGridViewTextBoxCell());
- dataGridViewRow1.Cells[index2].Value = (object) data[num + index1].ToString("x2");
- empty1 += HexView.toAscii(data[num + index1]).ToString();
- }
- else
- dataGridViewRow1.Cells.Add((DataGridViewCell) new DataGridViewTextBoxCell());
- }
- int index6 = dataGridViewRow1.Cells.Add((DataGridViewCell) new DataGridViewTextBoxCell());
- dataGridViewRow1.Cells[index6].Value = (object) empty1;
- dataGridView.Rows.Add(dataGridViewRow1);
- }
-
- private static void dumpToListView(byte[] data, ListView listView)
- {
- listView.Columns.Clear();
- listView.Items.Clear();
- listView.View = View.Details;
- listView.Font = new Font("Courier New", 9f);
- listView.Columns.Add("Offset", "Offset", 80, HorizontalAlignment.Left, string.Empty);
- for (int index = 0; index < 16; ++index)
- listView.Columns.Add(index.ToString("x1"), index.ToString("x1"), 30, HorizontalAlignment.Left, string.Empty);
- listView.Columns.Add("Dump", "Dump", 125, HorizontalAlignment.Left, string.Empty);
- int num;
- for (num = 0; (double) (data.Length - num) / 16.0 >= 1.0; num += 16)
- {
- ListViewItem listViewItem = new ListViewItem(num.ToString("x8"));
- string empty = string.Empty;
- for (int index = 0; index < 16; ++index)
- {
- listViewItem.SubItems.Add(data[num + index].ToString("x2"));
- empty += HexView.toAscii(data[num + index]).ToString();
- }
- listViewItem.SubItems.Add(empty);
- listView.Items.Add(listViewItem);
- }
- if (data.Length <= num)
- return;
- ListViewItem listViewItem1 = new ListViewItem(num.ToString("x8"));
- string empty1 = string.Empty;
- for (int index = 0; index < 16; ++index)
- {
- if (index < data.Length - num)
- {
- listViewItem1.SubItems.Add(data[num + index].ToString("x2"));
- empty1 += HexView.toAscii(data[num + index]).ToString();
- }
- else
- listViewItem1.SubItems.Add(string.Empty);
- }
- listViewItem1.SubItems.Add(empty1);
- listView.Items.Add(listViewItem1);
- }
-
- private static char toAscii(byte value) => value >= (byte) 32 && value <= (byte) 126 ? (char) value : '.';
-
- private static byte fromAscii(char value) => (byte) value;
- }
}
diff --git a/IosPatcher.cs b/IosPatcher.cs
index 82dd0e3..82c5d4d 100644
--- a/IosPatcher.cs
+++ b/IosPatcher.cs
@@ -1,8 +1,20 @@
-// Decompiled with JetBrains decompiler
-// Type: libWiiSharp.IosPatcher
-// Assembly: libWiiSharp, Version=0.4.0.0, Culture=neutral, PublicKeyToken=null
-// MVID: FBF36F3D-B5D6-481F-B5F5-1BD3C19E13B2
-// Assembly location: C:\Users\theso\Downloads\NCPatcher\pack\libWiiSharp.dll
+/* This file is part of libWiiSharp
+ * Copyright (C) 2009 Leathl
+ * Copyright (C) 2020 Github Contributors
+ *
+ * libWiiSharp 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.
+ *
+ * libWiiSharp 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.ComponentModel;
@@ -10,277 +22,314 @@ using System.Text;
namespace libWiiSharp
{
- public class IosPatcher
- {
- private WAD wadFile;
- private int esIndex = -1;
-
- public event EventHandler Progress;
-
- public event EventHandler Debug;
-
- public void LoadIOS(ref WAD iosWad)
+ ///
+ /// An IOS patcher which can patch fakesigning, es_identify and nand permissions.
+ ///
+ public class IosPatcher
{
- this.wadFile = iosWad;
- this.getEsIndex();
- }
+ private WAD wadFile;
+ private int esIndex = -1;
- public int PatchFakeSigning() => this.esIndex < 0 ? -1 : this.patchFakeSigning(ref this.wadFile.Contents[this.esIndex]);
-
- public int PatchEsIdentify() => this.esIndex < 0 ? -1 : this.patchEsIdentify(ref this.wadFile.Contents[this.esIndex]);
-
- public int PatchNandPermissions() => this.esIndex < 0 ? -1 : this.patchNandPermissions(ref this.wadFile.Contents[this.esIndex]);
-
- public int PatchVP() => this.esIndex < 0 ? -1 : this.patchVP(ref this.wadFile.Contents[this.esIndex]);
-
- public int PatchAll() => this.esIndex < 0 ? -1 : this.patchAll(ref this.wadFile.Contents[this.esIndex]);
-
- public int PatchFakeSigning(ref byte[] esModule) => this.patchFakeSigning(ref esModule);
-
- public int PatchEsIdentify(ref byte[] esModule) => this.patchEsIdentify(ref esModule);
-
- public int PatchNandPermissions(ref byte[] esModule) => this.patchNandPermissions(ref esModule);
-
- public int PatchVP(ref byte[] esModule) => this.patchVP(ref esModule);
-
- public int PatchAll(ref byte[] esModule) => this.patchAll(ref esModule);
-
- private int patchFakeSigning(ref byte[] esModule)
- {
- this.fireDebug("Patching Fakesigning...");
- int num = 0;
- byte[] second1 = new byte[4]
- {
- (byte) 32,
- (byte) 7,
- (byte) 35,
- (byte) 162
- };
- byte[] second2 = new byte[4]
- {
- (byte) 32,
- (byte) 7,
- (byte) 75,
- (byte) 11
- };
- for (int firstIndex = 0; firstIndex < esModule.Length - 4; ++firstIndex)
- {
- this.fireProgress((firstIndex + 1) * 100 / esModule.Length);
- if (Shared.CompareByteArrays(esModule, firstIndex, second1, 0, 4) || Shared.CompareByteArrays(esModule, firstIndex, second2, 0, 4))
+ #region Public Functions
+ ///
+ /// Loads an IOS wad to patch the es module.
+ ///
+ ///
+ public void LoadIOS(ref WAD iosWad)
{
- this.fireDebug(" Patching at Offset: 0x{0}", (object) firstIndex.ToString("x8").ToUpper());
- esModule[firstIndex + 1] = (byte) 0;
- firstIndex += 4;
- ++num;
+ this.wadFile = iosWad;
+ this.getEsIndex();
}
- }
- this.fireDebug("Patching Fakesigning Finished... (Patches applied: {0})", (object) num);
- return num;
- }
- private int patchEsIdentify(ref byte[] esModule)
- {
- this.fireDebug("Patching ES_Identify...");
- int num = 0;
- byte[] second = new byte[4]
- {
- (byte) 40,
- (byte) 3,
- (byte) 209,
- (byte) 35
- };
- for (int firstIndex = 0; firstIndex < esModule.Length - 4; ++firstIndex)
- {
- this.fireProgress((firstIndex + 1) * 100 / esModule.Length);
- if (Shared.CompareByteArrays(esModule, firstIndex, second, 0, 4))
- {
- this.fireDebug(" Patching at Offset: 0x{0}", (object) firstIndex.ToString("x8").ToUpper());
- esModule[firstIndex + 2] = (byte) 0;
- esModule[firstIndex + 3] = (byte) 0;
- firstIndex += 4;
- ++num;
- }
- }
- this.fireDebug("Patching ES_Identify Finished... (Patches applied: {0})", (object) num);
- return num;
- }
+ ///
+ /// Patches fakesigning.
+ /// Returns the number of applied patches.
+ ///
+ ///
+ public int PatchFakeSigning() => this.esIndex < 0 ? -1 : this.patchFakeSigning(ref this.wadFile.Contents[this.esIndex]);
- private int patchNandPermissions(ref byte[] esModule)
- {
- this.fireDebug("Patching NAND Permissions...");
- int num = 0;
- byte[] second = new byte[6]
- {
- (byte) 66,
- (byte) 139,
- (byte) 208,
- (byte) 1,
- (byte) 37,
- (byte) 102
- };
- for (int firstIndex = 0; firstIndex < esModule.Length - 6; ++firstIndex)
- {
- this.fireProgress((firstIndex + 1) * 100 / esModule.Length);
- if (Shared.CompareByteArrays(esModule, firstIndex, second, 0, 6))
- {
- this.fireDebug(" Patching at Offset: 0x{0}", (object) firstIndex.ToString("x8").ToUpper());
- esModule[firstIndex + 2] = (byte) 224;
- firstIndex += 6;
- ++num;
- }
- }
- this.fireDebug("Patching NAND Permissions Finished... (Patches applied: {0})", (object) num);
- return num;
- }
+ ///
+ /// Patches es_identify.
+ /// Returns the number of applied patches.
+ ///
+ ///
+ public int PatchEsIdentify() => this.esIndex < 0 ? -1 : this.patchEsIdentify(ref this.wadFile.Contents[this.esIndex]);
- private int patchVP(ref byte[] esModule)
- {
- this.fireDebug("Patching VP...");
- int num = 0;
- byte[] second = new byte[4]
- {
- (byte) 210,
- (byte) 1,
- (byte) 78,
- (byte) 86
- };
- for (int firstIndex = 0; firstIndex < esModule.Length - 4; ++firstIndex)
- {
- this.fireProgress((firstIndex + 1) * 100 / esModule.Length);
- if (Shared.CompareByteArrays(esModule, firstIndex, second, 0, 4))
- {
- this.fireDebug(" Patching for VP at Offset: 0x{0}", (object) firstIndex.ToString("x8").ToUpper());
- esModule[firstIndex] = (byte) 224;
- firstIndex += 4;
- ++num;
- }
- }
- this.fireDebug("Patching VP Finished... (Patches applied: {0})", (object) num);
- return num;
- }
+ ///
+ /// Patches nand permissions.
+ /// Returns the number of applied patches.
+ ///
+ ///
+ public int PatchNandPermissions() => this.esIndex < 0 ? -1 : this.patchNandPermissions(ref this.wadFile.Contents[this.esIndex]);
- private int patchAll(ref byte[] esModule)
- {
- this.fireDebug("Patching Fakesigning, ES_Identify, NAND Permissions and VP ...");
- int num = 0;
- byte[] second1 = new byte[4]
- {
- (byte) 32,
- (byte) 7,
- (byte) 35,
- (byte) 162
- };
- byte[] second2 = new byte[4]
- {
- (byte) 32,
- (byte) 7,
- (byte) 75,
- (byte) 11
- };
- byte[] second3 = new byte[4]
- {
- (byte) 40,
- (byte) 3,
- (byte) 209,
- (byte) 35
- };
- byte[] second4 = new byte[6]
- {
- (byte) 66,
- (byte) 139,
- (byte) 208,
- (byte) 1,
- (byte) 37,
- (byte) 102
- };
- byte[] second5 = new byte[4]
- {
- (byte) 210,
- (byte) 1,
- (byte) 78,
- (byte) 86
- };
- for (int firstIndex = 0; firstIndex < esModule.Length - 6; ++firstIndex)
- {
- this.fireProgress((firstIndex + 1) * 100 / esModule.Length);
- if (Shared.CompareByteArrays(esModule, firstIndex, second1, 0, 4) || Shared.CompareByteArrays(esModule, firstIndex, second2, 0, 4))
- {
- this.fireDebug(" Patching Fakesigning at Offset: 0x{0}", (object) firstIndex.ToString("x8").ToUpper());
- esModule[firstIndex + 1] = (byte) 0;
- firstIndex += 4;
- ++num;
- }
- else if (Shared.CompareByteArrays(esModule, firstIndex, second3, 0, 4))
- {
- this.fireDebug(" Patching ES_Identify at Offset: 0x{0}", (object) firstIndex.ToString("x8").ToUpper());
- esModule[firstIndex + 2] = (byte) 0;
- esModule[firstIndex + 3] = (byte) 0;
- firstIndex += 4;
- ++num;
- }
- else if (Shared.CompareByteArrays(esModule, firstIndex, second4, 0, 6))
- {
- this.fireDebug(" Patching NAND Permissions at Offset: 0x{0}", (object) firstIndex.ToString("x8").ToUpper());
- esModule[firstIndex + 2] = (byte) 224;
- firstIndex += 6;
- ++num;
- }
- else if (Shared.CompareByteArrays(esModule, firstIndex, second5, 0, 4))
- {
- this.fireDebug(" Patching VP at Offset: 0x{0}", (object) firstIndex.ToString("x8").ToUpper());
- esModule[firstIndex] = (byte) 224;
- firstIndex += 4;
- ++num;
- }
- }
- this.fireDebug("Patching Fakesigning, ES_Identify, NAND Permissions and VP Finished... (Patches applied: {0})", (object) num);
- return num;
- }
+ public int PatchVP() => this.esIndex < 0 ? -1 : this.patchVP(ref this.wadFile.Contents[this.esIndex]);
- private void getEsIndex()
- {
- this.fireDebug("Scanning for ES Module...");
- string str = "$IOSVersion:";
- for (int index1 = this.wadFile.NumOfContents - 1; index1 >= 0; --index1)
- {
- this.fireDebug(" Scanning Content #{0} of {1}...", (object) (index1 + 1), (object) this.wadFile.NumOfContents);
- this.fireProgress((index1 + 1) * 100 / this.wadFile.NumOfContents);
- for (int index2 = 0; index2 < this.wadFile.Contents[index1].Length - 64; ++index2)
+ ///
+ /// Patches fakesigning, es_identify and nand permissions.
+ /// Returns the number of applied patches.
+ ///
+ ///
+ public int PatchAll() => this.esIndex < 0 ? -1 : this.patchAll(ref this.wadFile.Contents[this.esIndex]);
+
+ public int PatchFakeSigning(ref byte[] esModule) => this.patchFakeSigning(ref esModule);
+
+ public int PatchEsIdentify(ref byte[] esModule) => this.patchEsIdentify(ref esModule);
+
+ public int PatchNandPermissions(ref byte[] esModule) => this.patchNandPermissions(ref esModule);
+
+ public int PatchVP(ref byte[] esModule) => this.patchVP(ref esModule);
+
+ public int PatchAll(ref byte[] esModule) => this.patchAll(ref esModule);
+ #endregion
+
+ #region Private Functions
+ private int patchFakeSigning(ref byte[] esModule)
{
- if (Encoding.ASCII.GetString(this.wadFile.Contents[index1], index2, 12) == str)
- {
- int index3 = index2 + 12;
- while (this.wadFile.Contents[index1][index3] == (byte) 32)
- ++index3;
- if (Encoding.ASCII.GetString(this.wadFile.Contents[index1], index3, 3) == "ES:")
+ this.fireDebug("Patching Fakesigning...");
+ int num = 0;
+ byte[] second1 = new byte[4]
{
- this.fireDebug(" -> ES Module found!");
- this.fireDebug("Scanning for ES Module Finished...");
- this.esIndex = index1;
- this.fireProgress(100);
- return;
+ (byte) 32,
+ (byte) 7,
+ (byte) 35,
+ (byte) 162
+ };
+ byte[] second2 = new byte[4]
+ {
+ (byte) 32,
+ (byte) 7,
+ (byte) 75,
+ (byte) 11
+ };
+ for (int firstIndex = 0; firstIndex < esModule.Length - 4; ++firstIndex)
+ {
+ this.fireProgress((firstIndex + 1) * 100 / esModule.Length);
+ if (Shared.CompareByteArrays(esModule, firstIndex, second1, 0, 4) || Shared.CompareByteArrays(esModule, firstIndex, second2, 0, 4))
+ {
+ this.fireDebug(" Patching at Offset: 0x{0}", (object) firstIndex.ToString("x8").ToUpper());
+ esModule[firstIndex + 1] = (byte) 0;
+ firstIndex += 4;
+ ++num;
+ }
}
- }
+ this.fireDebug("Patching Fakesigning Finished... (Patches applied: {0})", (object) num);
+ return num;
}
- }
- this.fireDebug("/!\\/!\\/!\\ ES Module wasn't found! /!\\/!\\/!\\");
- throw new Exception("ES module wasn't found!");
- }
- private void fireDebug(string debugMessage, params object[] args)
- {
- EventHandler debug = this.Debug;
- if (debug == null)
- return;
- debug(new object(), new MessageEventArgs(string.Format(debugMessage, args)));
- }
+ private int patchEsIdentify(ref byte[] esModule)
+ {
+ this.fireDebug("Patching ES_Identify...");
+ int num = 0;
+ byte[] second = new byte[4]
+ {
+ (byte) 40,
+ (byte) 3,
+ (byte) 209,
+ (byte) 35
+ };
+ for (int firstIndex = 0; firstIndex < esModule.Length - 4; ++firstIndex)
+ {
+ this.fireProgress((firstIndex + 1) * 100 / esModule.Length);
+ if (Shared.CompareByteArrays(esModule, firstIndex, second, 0, 4))
+ {
+ this.fireDebug(" Patching at Offset: 0x{0}", (object) firstIndex.ToString("x8").ToUpper());
+ esModule[firstIndex + 2] = (byte) 0;
+ esModule[firstIndex + 3] = (byte) 0;
+ firstIndex += 4;
+ ++num;
+ }
+ }
+ this.fireDebug("Patching ES_Identify Finished... (Patches applied: {0})", (object) num);
+ return num;
+ }
- private void fireProgress(int progressPercentage)
- {
- EventHandler progress = this.Progress;
- if (progress == null)
- return;
- progress(new object(), new ProgressChangedEventArgs(progressPercentage, (object) string.Empty));
+ private int patchNandPermissions(ref byte[] esModule)
+ {
+ this.fireDebug("Patching NAND Permissions...");
+ int num = 0;
+ byte[] second = new byte[6]
+ {
+ (byte) 66,
+ (byte) 139,
+ (byte) 208,
+ (byte) 1,
+ (byte) 37,
+ (byte) 102
+ };
+ for (int firstIndex = 0; firstIndex < esModule.Length - 6; ++firstIndex)
+ {
+ this.fireProgress((firstIndex + 1) * 100 / esModule.Length);
+ if (Shared.CompareByteArrays(esModule, firstIndex, second, 0, 6))
+ {
+ this.fireDebug(" Patching at Offset: 0x{0}", (object) firstIndex.ToString("x8").ToUpper());
+ esModule[firstIndex + 2] = (byte) 224;
+ firstIndex += 6;
+ ++num;
+ }
+ }
+ this.fireDebug("Patching NAND Permissions Finished... (Patches applied: {0})", (object) num);
+ return num;
+ }
+
+ private int patchVP(ref byte[] esModule)
+ {
+ this.fireDebug("Patching VP...");
+ int num = 0;
+ byte[] second = new byte[4]
+ {
+ (byte) 210,
+ (byte) 1,
+ (byte) 78,
+ (byte) 86
+ };
+ for (int firstIndex = 0; firstIndex < esModule.Length - 4; ++firstIndex)
+ {
+ this.fireProgress((firstIndex + 1) * 100 / esModule.Length);
+ if (Shared.CompareByteArrays(esModule, firstIndex, second, 0, 4))
+ {
+ this.fireDebug(" Patching for VP at Offset: 0x{0}", (object) firstIndex.ToString("x8").ToUpper());
+ esModule[firstIndex] = (byte) 224;
+ firstIndex += 4;
+ ++num;
+ }
+ }
+ this.fireDebug("Patching VP Finished... (Patches applied: {0})", (object) num);
+ return num;
+ }
+
+ private int patchAll(ref byte[] esModule)
+ {
+ this.fireDebug("Patching Fakesigning, ES_Identify, NAND Permissions and VP ...");
+ int num = 0;
+ byte[] second1 = new byte[4]
+ {
+ (byte) 32,
+ (byte) 7,
+ (byte) 35,
+ (byte) 162
+ };
+ byte[] second2 = new byte[4]
+ {
+ (byte) 32,
+ (byte) 7,
+ (byte) 75,
+ (byte) 11
+ };
+ byte[] second3 = new byte[4]
+ {
+ (byte) 40,
+ (byte) 3,
+ (byte) 209,
+ (byte) 35
+ };
+ byte[] second4 = new byte[6]
+ {
+ (byte) 66,
+ (byte) 139,
+ (byte) 208,
+ (byte) 1,
+ (byte) 37,
+ (byte) 102
+ };
+ byte[] second5 = new byte[4]
+ {
+ (byte) 210,
+ (byte) 1,
+ (byte) 78,
+ (byte) 86
+ };
+ for (int firstIndex = 0; firstIndex < esModule.Length - 6; ++firstIndex)
+ {
+ this.fireProgress((firstIndex + 1) * 100 / esModule.Length);
+ if (Shared.CompareByteArrays(esModule, firstIndex, second1, 0, 4) || Shared.CompareByteArrays(esModule, firstIndex, second2, 0, 4))
+ {
+ this.fireDebug(" Patching Fakesigning at Offset: 0x{0}", (object) firstIndex.ToString("x8").ToUpper());
+ esModule[firstIndex + 1] = (byte) 0;
+ firstIndex += 4;
+ ++num;
+ }
+ else if (Shared.CompareByteArrays(esModule, firstIndex, second3, 0, 4))
+ {
+ this.fireDebug(" Patching ES_Identify at Offset: 0x{0}", (object) firstIndex.ToString("x8").ToUpper());
+ esModule[firstIndex + 2] = (byte) 0;
+ esModule[firstIndex + 3] = (byte) 0;
+ firstIndex += 4;
+ ++num;
+ }
+ else if (Shared.CompareByteArrays(esModule, firstIndex, second4, 0, 6))
+ {
+ this.fireDebug(" Patching NAND Permissions at Offset: 0x{0}", (object) firstIndex.ToString("x8").ToUpper());
+ esModule[firstIndex + 2] = (byte) 224;
+ firstIndex += 6;
+ ++num;
+ }
+ else if (Shared.CompareByteArrays(esModule, firstIndex, second5, 0, 4))
+ {
+ this.fireDebug(" Patching VP at Offset: 0x{0}", (object) firstIndex.ToString("x8").ToUpper());
+ esModule[firstIndex] = (byte) 224;
+ firstIndex += 4;
+ ++num;
+ }
+ }
+ this.fireDebug("Patching Fakesigning, ES_Identify, NAND Permissions and VP Finished... (Patches applied: {0})", (object) num);
+ return num;
+ }
+
+ private void getEsIndex()
+ {
+ this.fireDebug("Scanning for ES Module...");
+ string str = "$IOSVersion:";
+ for (int index1 = this.wadFile.NumOfContents - 1; index1 >= 0; --index1)
+ {
+ this.fireDebug(" Scanning Content #{0} of {1}...", (object) (index1 + 1), (object) this.wadFile.NumOfContents);
+ this.fireProgress((index1 + 1) * 100 / this.wadFile.NumOfContents);
+ for (int index2 = 0; index2 < this.wadFile.Contents[index1].Length - 64; ++index2)
+ {
+ if (Encoding.ASCII.GetString(this.wadFile.Contents[index1], index2, 12) == str)
+ {
+ int index3 = index2 + 12;
+ while (this.wadFile.Contents[index1][index3] == (byte) 32)
+ ++index3;
+ if (Encoding.ASCII.GetString(this.wadFile.Contents[index1], index3, 3) == "ES:")
+ {
+ this.fireDebug(" -> ES Module found!");
+ this.fireDebug("Scanning for ES Module Finished...");
+ this.esIndex = index1;
+ this.fireProgress(100);
+ return;
+ }
+ }
+ }
+ }
+ this.fireDebug("/!\\/!\\/!\\ ES Module wasn't found! /!\\/!\\/!\\");
+ throw new Exception("ES module wasn't found!");
+ }
+ #endregion
+
+ #region Events
+ ///
+ /// Fires the Progress of various operations
+ ///
+ public event EventHandler Progress;
+ ///
+ /// Fires debugging messages. You may write them into a log file or log textbox.
+ ///
+ public event EventHandler Debug;
+ private void fireDebug(string debugMessage, params object[] args)
+ {
+ EventHandler debug = this.Debug;
+ if (debug == null)
+ return;
+ debug(new object(), new MessageEventArgs(string.Format(debugMessage, args)));
+ }
+
+ private void fireProgress(int progressPercentage)
+ {
+ EventHandler progress = this.Progress;
+ if (progress == null)
+ return;
+ progress(new object(), new ProgressChangedEventArgs(progressPercentage, (object) string.Empty));
+ }
+ #endregion
}
- }
}
diff --git a/LowerTitleID.cs b/LowerTitleID.cs
deleted file mode 100644
index bd9b486..0000000
--- a/LowerTitleID.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-// Decompiled with JetBrains decompiler
-// Type: libWiiSharp.LowerTitleID
-// Assembly: libWiiSharp, Version=0.4.0.0, Culture=neutral, PublicKeyToken=null
-// MVID: FBF36F3D-B5D6-481F-B5F5-1BD3C19E13B2
-// Assembly location: C:\Users\theso\Downloads\NCPatcher\pack\libWiiSharp.dll
-
-namespace libWiiSharp
-{
- public enum LowerTitleID : uint
- {
- SystemTitles = 1,
- Channel = 65537, // 0x00010001
- SystemChannels = 65538, // 0x00010002
- GameChannel = 65540, // 0x00010004
- DLC = 65541, // 0x00010005
- HiddenChannels = 65544, // 0x00010008
- }
-}
diff --git a/Protocol.cs b/Protocol.cs
deleted file mode 100644
index a695c31..0000000
--- a/Protocol.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-// Decompiled with JetBrains decompiler
-// Type: libWiiSharp.Protocol
-// Assembly: libWiiSharp, Version=0.4.0.0, Culture=neutral, PublicKeyToken=null
-// MVID: FBF36F3D-B5D6-481F-B5F5-1BD3C19E13B2
-// Assembly location: C:\Users\theso\Downloads\NCPatcher\pack\libWiiSharp.dll
-
-namespace libWiiSharp
-{
- public enum Protocol
- {
- HAXX,
- JODI,
- Custom,
- }
-}
diff --git a/TMD.cs b/TMD.cs
index 8023f54..f5bc11b 100644
--- a/TMD.cs
+++ b/TMD.cs
@@ -11,7 +11,13 @@ using System.Security.Cryptography;
namespace libWiiSharp
{
- public class TMD : IDisposable
+ public enum ContentType : ushort
+ {
+ Normal = 1,
+ DLC = 16385, // 0x4001
+ Shared = 32769, // 0x8001
+ }
+ public class TMD : IDisposable
{
private bool fakeSign;
private bool sortContents;
diff --git a/Ticket.cs b/Ticket.cs
index b982e67..fe2f306 100644
--- a/Ticket.cs
+++ b/Ticket.cs
@@ -10,8 +10,15 @@ using System.Security.Cryptography;
namespace libWiiSharp
{
- public class Ticket : IDisposable
- {
+
+ public enum CommonKeyType : byte
+ {
+ Standard = 0x00,
+ Korean = 0x01,
+ }
+
+ public class Ticket : IDisposable
+ {
private byte newKeyIndex;
private byte[] decryptedTitleKey = new byte[16];
private bool fakeSign;
diff --git a/WAD.cs b/WAD.cs
index f1019fa..46cb065 100644
--- a/WAD.cs
+++ b/WAD.cs
@@ -13,7 +13,16 @@ using System.Text;
namespace libWiiSharp
{
- public class WAD : IDisposable
+ public enum LowerTitleID : uint
+ {
+ SystemTitles = 0x00000001,
+ SystemChannels = 0x00010002,
+ Channel = 0x00010001,
+ GameChannel = 0x00010004,
+ DLC = 0x00010005,
+ HiddenChannels = 0x00010008,
+ }
+ public class WAD : IDisposable
{
private SHA1 sha = SHA1.Create();
private DateTime creationTimeUTC = new DateTime(1970, 1, 1);
@@ -999,4 +1008,38 @@ namespace libWiiSharp
private void bannerApp_Warning(object sender, MessageEventArgs e) => this.fireWarning(e.Message);
}
+
+ public class WAD_Header
+ {
+ private uint headerSize = 0x20;
+ private uint wadType = 0x49730000;
+ private uint certSize = 0xA00;
+ private uint reserved = 0x00;
+ private uint tikSize = 0x2A4;
+ private uint tmdSize;
+ private uint contentSize;
+ private uint footerSize = 0x00;
+
+ public uint HeaderSize { get { return headerSize; } }
+ public uint WadType { get { return wadType; } set { wadType = value; } }
+ public uint CertSize { get { return certSize; } }
+ public uint Reserved { get { return reserved; } }
+ public uint TicketSize { get { return tikSize; } }
+ public uint TmdSize { get { return tmdSize; } set { tmdSize = value; } }
+ public uint ContentSize { get { return contentSize; } set { contentSize = value; } }
+ public uint FooterSize { get { return footerSize; } set { footerSize = value; } }
+
+ public void Write(Stream writeStream)
+ {
+ writeStream.Seek(0, SeekOrigin.Begin);
+ writeStream.Write(BitConverter.GetBytes(Shared.Swap(headerSize)), 0, 4);
+ writeStream.Write(BitConverter.GetBytes(Shared.Swap(wadType)), 0, 4);
+ writeStream.Write(BitConverter.GetBytes(Shared.Swap(certSize)), 0, 4);
+ writeStream.Write(BitConverter.GetBytes(Shared.Swap(reserved)), 0, 4);
+ writeStream.Write(BitConverter.GetBytes(Shared.Swap(tikSize)), 0, 4);
+ writeStream.Write(BitConverter.GetBytes(Shared.Swap(tmdSize)), 0, 4);
+ writeStream.Write(BitConverter.GetBytes(Shared.Swap(contentSize)), 0, 4);
+ writeStream.Write(BitConverter.GetBytes(Shared.Swap(footerSize)), 0, 4);
+ }
+ }
}
diff --git a/WAD_Header.cs b/WAD_Header.cs
deleted file mode 100644
index 5579902..0000000
--- a/WAD_Header.cs
+++ /dev/null
@@ -1,68 +0,0 @@
-// Decompiled with JetBrains decompiler
-// Type: libWiiSharp.WAD_Header
-// Assembly: libWiiSharp, Version=0.4.0.0, Culture=neutral, PublicKeyToken=null
-// MVID: FBF36F3D-B5D6-481F-B5F5-1BD3C19E13B2
-// Assembly location: C:\Users\theso\Downloads\NCPatcher\pack\libWiiSharp.dll
-
-using System;
-using System.IO;
-
-namespace libWiiSharp
-{
- public class WAD_Header
- {
- private uint headerSize = 32;
- private uint wadType = 1232273408;
- private uint certSize = 2560;
- private uint reserved;
- private uint tikSize = 676;
- private uint tmdSize;
- private uint contentSize;
- private uint footerSize;
-
- public uint HeaderSize => this.headerSize;
-
- public uint WadType
- {
- get => this.wadType;
- set => this.wadType = value;
- }
-
- public uint CertSize => this.certSize;
-
- public uint Reserved => this.reserved;
-
- public uint TicketSize => this.tikSize;
-
- public uint TmdSize
- {
- get => this.tmdSize;
- set => this.tmdSize = value;
- }
-
- public uint ContentSize
- {
- get => this.contentSize;
- set => this.contentSize = value;
- }
-
- public uint FooterSize
- {
- get => this.footerSize;
- set => this.footerSize = value;
- }
-
- public void Write(Stream writeStream)
- {
- writeStream.Seek(0L, SeekOrigin.Begin);
- writeStream.Write(BitConverter.GetBytes(Shared.Swap(this.headerSize)), 0, 4);
- writeStream.Write(BitConverter.GetBytes(Shared.Swap(this.wadType)), 0, 4);
- writeStream.Write(BitConverter.GetBytes(Shared.Swap(this.certSize)), 0, 4);
- writeStream.Write(BitConverter.GetBytes(Shared.Swap(this.reserved)), 0, 4);
- writeStream.Write(BitConverter.GetBytes(Shared.Swap(this.tikSize)), 0, 4);
- writeStream.Write(BitConverter.GetBytes(Shared.Swap(this.tmdSize)), 0, 4);
- writeStream.Write(BitConverter.GetBytes(Shared.Swap(this.contentSize)), 0, 4);
- writeStream.Write(BitConverter.GetBytes(Shared.Swap(this.footerSize)), 0, 4);
- }
- }
-}
diff --git a/libWiiSharp.csproj b/libWiiSharp.csproj
index bd7f885..9b1e20a 100644
--- a/libWiiSharp.csproj
+++ b/libWiiSharp.csproj
@@ -55,18 +55,14 @@
-
-
-
-
@@ -85,14 +81,12 @@
-
-
diff --git a/libWiiSharp.csproj.user b/libWiiSharp.csproj.user
new file mode 100644
index 0000000..c10e84b
--- /dev/null
+++ b/libWiiSharp.csproj.user
@@ -0,0 +1,6 @@
+
+
+
+ ProjectFiles
+
+
\ No newline at end of file
diff --git a/zlibWrapper.cs b/zlibWrapper.cs
deleted file mode 100644
index 2c61042..0000000
--- a/zlibWrapper.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-// Decompiled with JetBrains decompiler
-// Type: libWiiSharp.zlibWrapper
-// Assembly: libWiiSharp, Version=0.4.0.0, Culture=neutral, PublicKeyToken=null
-// MVID: FBF36F3D-B5D6-481F-B5F5-1BD3C19E13B2
-// Assembly location: C:\Users\theso\Downloads\NCPatcher\pack\libWiiSharp.dll
-
-using System;
-using System.Runtime.InteropServices;
-
-namespace libWiiSharp
-{
- internal class zlibWrapper
- {
- [DllImport("zlib1.dll")]
- private static extern zlibWrapper.ZLibError compress2(
- byte[] dest,
- ref int destLength,
- byte[] source,
- int sourceLength,
- int level);
-
- public static byte[] Compress(byte[] inFile)
- {
- byte[] array = new byte[inFile.Length + 64];
- int destLength = -1;
- zlibWrapper.ZLibError zlibError = zlibWrapper.compress2(array, ref destLength, inFile, inFile.Length, 6);
- if (zlibError != zlibWrapper.ZLibError.Z_OK || destLength <= -1 || destLength >= inFile.Length)
- throw new Exception("An error occured while compressing! Code: " + zlibError.ToString());
- Array.Resize(ref array, destLength);
- return array;
- }
-
- public enum ZLibError
- {
- Z_VERSION_ERROR = -6, // 0xFFFFFFFA
- Z_BUF_ERROR = -5, // 0xFFFFFFFB
- Z_MEM_ERROR = -4, // 0xFFFFFFFC
- Z_DATA_ERROR = -3, // 0xFFFFFFFD
- Z_STREAM_ERROR = -2, // 0xFFFFFFFE
- Z_ERRNO = -1, // 0xFFFFFFFF
- Z_OK = 0,
- Z_STREAM_END = 1,
- Z_NEED_DICT = 2,
- }
- }
-}